From 5dfb48c2d48dd80fb38770b23efabc5cb5c05419 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 21 Apr 2015 17:26:18 +0000 Subject: [PATCH] Fix __alignof__ of global variables on SystemZ SystemZ prefers to align all global variables to two bytes, which is implemented by setting the TargetInfo member MinGlobalAlign. However, for compatibility with existing compilers this should *not* change the ABI alignment value as retrieved via __alignof__, which it currently does. This patch fixes the issue by having ASTContext::getDeclAlign ignore the MinGlobalAlign setting in the ForAlignof case. Since SystemZ is the only platform setting MinGlobalAlign, this should cause no change for any other target. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@235395 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTContext.cpp | 2 +- test/CodeGen/align-systemz.c | 14 ++++++++++++++ test/Sema/align-systemz.c | 17 +++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/align-systemz.c create mode 100644 test/Sema/align-systemz.c diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 899f8c5ff5..c54a006d26 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1335,7 +1335,7 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const { } Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr())); if (const VarDecl *VD = dyn_cast(D)) { - if (VD->hasGlobalStorage()) + if (VD->hasGlobalStorage() && !ForAlignof) Align = std::max(Align, getTargetInfo().getMinGlobalAlign()); } } diff --git a/test/CodeGen/align-systemz.c b/test/CodeGen/align-systemz.c new file mode 100644 index 0000000000..277492c060 --- /dev/null +++ b/test/CodeGen/align-systemz.c @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -emit-llvm %s -o - | FileCheck %s + +// SystemZ prefers to align all global variables to two bytes. + +struct test { + signed char a; +}; + +char c; +// CHECK-DAG: @c = common global i8 0, align 2 + +struct test s; +// CHECK-DAG: @s = common global %struct.test zeroinitializer, align 2 + diff --git a/test/Sema/align-systemz.c b/test/Sema/align-systemz.c new file mode 100644 index 0000000000..6928549de1 --- /dev/null +++ b/test/Sema/align-systemz.c @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -triple s390x-linux-gnu -fsyntax-only -verify %s +// expected-no-diagnostics + +// SystemZ prefers to align all global variables to two bytes, +// but this should *not* be reflected in the ABI alignment as +// retrieved via __alignof__. + +struct test { + signed char a; +}; + +char c; +struct test s; + +int chk1[__alignof__(c) == 1 ? 1 : -1]; +int chk2[__alignof__(s) == 1 ? 1 : -1]; + -- 2.40.0