llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Jonas Paulsson (JonPsson1) <details> <summary>Changes</summary> The SystemZ ABI requires any global variable to be aligned to at least 2 bytes, and therefore an external global Value with an opaque type should get this alignment as well. --- Full diff: https://github.com/llvm/llvm-project/pull/72886.diff 2 Files Affected: - (modified) clang/lib/AST/ASTContext.cpp (+8-6) - (added) clang/test/Driver/systemz-alignment.c (+32) ``````````diff diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1c893d008cb49f3..a7cee3b7ba2b0db 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1680,14 +1680,16 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr())); if (BaseT.getQualifiers().hasUnaligned()) Align = Target->getCharWidth(); - if (const auto *VD = dyn_cast<VarDecl>(D)) { - if (VD->hasGlobalStorage() && !ForAlignof) { - uint64_t TypeSize = getTypeSize(T.getTypePtr()); - Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); - } - } } + // Ensure miminum alignment for global variables. + if (const auto *VD = dyn_cast<VarDecl>(D)) + if (VD->hasGlobalStorage() && !ForAlignof) { + uint64_t TypeSize = + !BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0; + Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize)); + } + // Fields can be subject to extra alignment constraints, like if // the field is packed, the struct is packed, or the struct has a // a max-field-alignment constraint (#pragma pack). So calculate diff --git a/clang/test/Driver/systemz-alignment.c b/clang/test/Driver/systemz-alignment.c new file mode 100644 index 000000000000000..6f3b2bc38be3688 --- /dev/null +++ b/clang/test/Driver/systemz-alignment.c @@ -0,0 +1,32 @@ +// RUN: %clang --target=s390x-linux -S -emit-llvm -o - %s | FileCheck %s +// +// Test that a global variable with an incomplete type gets the minimum +// alignment of 2 per the ABI if no alignment was specified by user. +// +// CHECK: @VarNoAl {{.*}} align 2 +// CHECK-NEXT: @VarExplAl1 {{.*}} align 1 +// CHECK-NEXT: @VarExplAl4 {{.*}} align 4 + +// No alignemnt specified by user. +struct incomplete_ty_noal; +extern struct incomplete_ty_noal VarNoAl; +struct incomplete_ty_noal *fun0 (void) +{ + return &VarNoAl; +} + +// User-specified alignment of 1. +struct incomplete_ty_al1; +extern struct incomplete_ty_al1 __attribute__((aligned(1))) VarExplAl1; +struct incomplete_ty_al1 *fun1 (void) +{ + return &VarExplAl1; +} + +// User-specified alignment of 4. +struct incomplete_ty_al4; +extern struct incomplete_ty_al4 __attribute__((aligned(4))) VarExplAl4; +struct incomplete_ty_al4 *fun2 (void) +{ + return &VarExplAl4; +} `````````` </details> https://github.com/llvm/llvm-project/pull/72886 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits