forked from OSchip/llvm-project
[clang codegen] Use IR "align" attribute for static array arguments.
Without the "align" attribute, marking the argument dereferenceable is basically useless. See also D80166. Fixes https://bugs.llvm.org/show_bug.cgi?id=46876 . Differential Revision: https://reviews.llvm.org/D84992
This commit is contained in:
parent
6b1f9f2bd4
commit
673dbe1b5e
|
@ -2520,6 +2520,9 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
|
||||||
// bytes).
|
// bytes).
|
||||||
if (ArrTy->getSizeModifier() == ArrayType::Static) {
|
if (ArrTy->getSizeModifier() == ArrayType::Static) {
|
||||||
QualType ETy = ArrTy->getElementType();
|
QualType ETy = ArrTy->getElementType();
|
||||||
|
llvm::Align Alignment =
|
||||||
|
CGM.getNaturalTypeAlignment(ETy).getAsAlign();
|
||||||
|
AI->addAttrs(llvm::AttrBuilder().addAlignmentAttr(Alignment));
|
||||||
uint64_t ArrSize = ArrTy->getSize().getZExtValue();
|
uint64_t ArrSize = ArrTy->getSize().getZExtValue();
|
||||||
if (!ETy->isIncompleteType() && ETy->isConstantSizeType() &&
|
if (!ETy->isIncompleteType() && ETy->isConstantSizeType() &&
|
||||||
ArrSize) {
|
ArrSize) {
|
||||||
|
@ -2539,10 +2542,15 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
|
||||||
// For C99 VLAs with the static keyword, we don't know the size so
|
// For C99 VLAs with the static keyword, we don't know the size so
|
||||||
// we can't use the dereferenceable attribute, but in addrspace(0)
|
// we can't use the dereferenceable attribute, but in addrspace(0)
|
||||||
// we know that it must be nonnull.
|
// we know that it must be nonnull.
|
||||||
if (ArrTy->getSizeModifier() == VariableArrayType::Static &&
|
if (ArrTy->getSizeModifier() == VariableArrayType::Static) {
|
||||||
!getContext().getTargetAddressSpace(ArrTy->getElementType()) &&
|
QualType ETy = ArrTy->getElementType();
|
||||||
!CGM.getCodeGenOpts().NullPointerIsValid)
|
llvm::Align Alignment =
|
||||||
AI->addAttr(llvm::Attribute::NonNull);
|
CGM.getNaturalTypeAlignment(ETy).getAsAlign();
|
||||||
|
AI->addAttrs(llvm::AttrBuilder().addAlignmentAttr(Alignment));
|
||||||
|
if (!getContext().getTargetAddressSpace(ETy) &&
|
||||||
|
!CGM.getCodeGenOpts().NullPointerIsValid)
|
||||||
|
AI->addAttr(llvm::Attribute::NonNull);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set `align` attribute if any.
|
// Set `align` attribute if any.
|
||||||
|
|
|
@ -200,13 +200,13 @@ void test7(int a[b(0)]) {
|
||||||
// Make sure we emit dereferenceable or nonnull when the static keyword is
|
// Make sure we emit dereferenceable or nonnull when the static keyword is
|
||||||
// provided.
|
// provided.
|
||||||
void test8(int a[static 3]) { }
|
void test8(int a[static 3]) { }
|
||||||
// CHECK: define void @test8(i32* dereferenceable(12) %a)
|
// CHECK: define void @test8(i32* align 4 dereferenceable(12) %a)
|
||||||
|
|
||||||
void test9(int n, int a[static n]) { }
|
void test9(int n, int a[static n]) { }
|
||||||
// NULL-INVALID: define void @test9(i32 %n, i32* nonnull %a)
|
// NULL-INVALID: define void @test9(i32 %n, i32* nonnull align 4 %a)
|
||||||
// NULL-VALID: define void @test9(i32 %n, i32* %a)
|
// NULL-VALID: define void @test9(i32 %n, i32* align 4 %a)
|
||||||
|
|
||||||
// Make sure a zero-sized static array extent is still required to be nonnull.
|
// Make sure a zero-sized static array extent is still required to be nonnull.
|
||||||
void test10(int a[static 0]) {}
|
void test10(int a[static 0]) {}
|
||||||
// NULL-INVALID: define void @test10(i32* nonnull %a)
|
// NULL-INVALID: define void @test10(i32* nonnull align 4 %a)
|
||||||
// NULL-VALID: define void @test10(i32* %a)
|
// NULL-VALID: define void @test10(i32* align 4 %a)
|
||||||
|
|
Loading…
Reference in New Issue