From 673dbe1b5eef09db39783c828a84f1213a47bad0 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Thu, 30 Jul 2020 17:32:39 -0700 Subject: [PATCH] [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 --- clang/lib/CodeGen/CGCall.cpp | 16 ++++++++++++---- clang/test/CodeGen/vla.c | 10 +++++----- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 9d225b23e3c3..98ba1efc20de 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2520,6 +2520,9 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, // bytes). if (ArrTy->getSizeModifier() == ArrayType::Static) { QualType ETy = ArrTy->getElementType(); + llvm::Align Alignment = + CGM.getNaturalTypeAlignment(ETy).getAsAlign(); + AI->addAttrs(llvm::AttrBuilder().addAlignmentAttr(Alignment)); uint64_t ArrSize = ArrTy->getSize().getZExtValue(); if (!ETy->isIncompleteType() && ETy->isConstantSizeType() && 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 // we can't use the dereferenceable attribute, but in addrspace(0) // we know that it must be nonnull. - if (ArrTy->getSizeModifier() == VariableArrayType::Static && - !getContext().getTargetAddressSpace(ArrTy->getElementType()) && - !CGM.getCodeGenOpts().NullPointerIsValid) - AI->addAttr(llvm::Attribute::NonNull); + if (ArrTy->getSizeModifier() == VariableArrayType::Static) { + QualType ETy = ArrTy->getElementType(); + llvm::Align Alignment = + 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. diff --git a/clang/test/CodeGen/vla.c b/clang/test/CodeGen/vla.c index 16b82f4acc7d..3142050149aa 100644 --- a/clang/test/CodeGen/vla.c +++ b/clang/test/CodeGen/vla.c @@ -200,13 +200,13 @@ void test7(int a[b(0)]) { // Make sure we emit dereferenceable or nonnull when the static keyword is // provided. 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]) { } -// NULL-INVALID: define void @test9(i32 %n, i32* nonnull %a) -// NULL-VALID: define void @test9(i32 %n, i32* %a) +// NULL-INVALID: define void @test9(i32 %n, i32* nonnull align 4 %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. void test10(int a[static 0]) {} -// NULL-INVALID: define void @test10(i32* nonnull %a) -// NULL-VALID: define void @test10(i32* %a) +// NULL-INVALID: define void @test10(i32* nonnull align 4 %a) +// NULL-VALID: define void @test10(i32* align 4 %a)