r235976 - [ARM/AArch64] Enforce alignment for bitfielded structs

Bradley Smith bradley.smith at arm.com
Tue Apr 28 04:24:55 PDT 2015


Author: brasmi01
Date: Tue Apr 28 06:24:54 2015
New Revision: 235976

URL: http://llvm.org/viewvc/llvm-project?rev=235976&view=rev
Log:
[ARM/AArch64] Enforce alignment for bitfielded structs

When creating a global variable with a type of a struct with bitfields, we must
forcibly set the alignment of the global from the RecordDecl. We must do this so
that the proper bitfield alignment makes its way down to LLVM, since clang will
mangle the bitfields into one large type.


Added:
    cfe/trunk/test/CodeGen/arm-bitfield-alignment.c   (with props)
Modified:
    cfe/trunk/include/clang/Basic/TargetInfo.h
    cfe/trunk/lib/Basic/TargetInfo.cpp
    cfe/trunk/lib/Basic/Targets.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp

Modified: cfe/trunk/include/clang/Basic/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TargetInfo.h?rev=235976&r1=235975&r2=235976&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TargetInfo.h (original)
+++ cfe/trunk/include/clang/Basic/TargetInfo.h Tue Apr 28 06:24:54 2015
@@ -204,6 +204,11 @@ protected:
   /// not for language specific address spaces
   bool UseAddrSpaceMapMangling;
 
+  /// \brief Specify if globals of a struct type containing bitfields should
+  /// have their alignment explicitly specified so as to ensure that LLVM uses
+  /// the correct alignment
+  bool EnforceBitfieldContainerAlignment;
+
 public:
   IntType getSizeType() const { return SizeType; }
   IntType getIntMaxType() const { return IntMaxType; }
@@ -454,6 +459,11 @@ public:
     return HasAlignMac68kSupport;
   }
 
+  /// \brief Check whether the alignment of bitfield struct should be enforced
+  bool enforceBitfieldContainerAlignment() const {
+    return EnforceBitfieldContainerAlignment;
+  }
+
   /// \brief Return the user string for the specified integer type enum.
   ///
   /// For example, SignedShort -> "short".

Modified: cfe/trunk/lib/Basic/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/TargetInfo.cpp?rev=235976&r1=235975&r2=235976&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/TargetInfo.cpp (original)
+++ cfe/trunk/lib/Basic/TargetInfo.cpp Tue Apr 28 06:24:54 2015
@@ -75,6 +75,7 @@ TargetInfo::TargetInfo(const llvm::Tripl
   RegParmMax = 0;
   SSERegParmMax = 0;
   HasAlignMac68kSupport = false;
+  EnforceBitfieldContainerAlignment = false;
 
   // Default to no types using fpret.
   RealTypeUsesObjCFPRet = 0;

Modified: cfe/trunk/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=235976&r1=235975&r2=235976&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Targets.cpp (original)
+++ cfe/trunk/lib/Basic/Targets.cpp Tue Apr 28 06:24:54 2015
@@ -3983,6 +3983,9 @@ class ARMTargetInfo : public TargetInfo
 
     ZeroLengthBitfieldBoundary = 0;
 
+    // Enforce the alignment of bitfield structs
+    EnforceBitfieldContainerAlignment = true;
+
     // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
     // so set preferred for small types to 32.
     if (T.isOSBinFormatMachO()) {
@@ -4825,6 +4828,9 @@ public:
     UseBitFieldTypeAlignment = true;
     UseZeroLengthBitfieldAlignment = true;
 
+    // Enforce the alignment of bitfield structs
+    EnforceBitfieldContainerAlignment = true;
+
     // AArch64 targets default to using the ARM C++ ABI.
     TheCXXABI.set(TargetCXXABI::GenericAArch64);
   }

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=235976&r1=235975&r2=235976&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Apr 28 06:24:54 2015
@@ -1799,6 +1799,23 @@ CodeGenModule::GetOrCreateLLVMGlobal(Str
         D->getType().isConstant(Context) &&
         isExternallyVisible(D->getLinkageAndVisibility().getLinkage()))
       GV->setSection(".cp.rodata");
+
+    // The ARM/AArch64 ABI expects structs with bitfields to respect the proper
+    // container alignment, hence we have to enfore this in the IR so as to
+    // work around clang combining bitfields into one large type.
+    if (getContext().getTargetInfo().enforceBitfieldContainerAlignment()) {
+      if (const auto *RT = D->getType()->getAs<RecordType>()) {
+        const RecordDecl *RD = RT->getDecl();
+
+        for (auto I = RD->field_begin(), End = RD->field_end(); I != End; ++I) {
+          if ((*I)->isBitField()) {
+            const ASTRecordLayout &Info = getContext().getASTRecordLayout(RD);
+            GV->setAlignment(Info.getAlignment().getQuantity());
+            break;
+          }
+        }
+      }
+    }
   }
 
   if (AddrSpace != Ty->getAddressSpace())

Added: cfe/trunk/test/CodeGen/arm-bitfield-alignment.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm-bitfield-alignment.c?rev=235976&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/arm-bitfield-alignment.c (added)
+++ cfe/trunk/test/CodeGen/arm-bitfield-alignment.c Tue Apr 28 06:24:54 2015
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple arm-none-eabi -ffreestanding -emit-llvm -o - -O3 %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64 -ffreestanding -emit-llvm -o - -O3 %s | FileCheck %s
+
+extern struct T {
+  int b0 : 8;
+  int b1 : 24;
+  int b2 : 1;
+} g;
+
+int func() {
+  return g.b1;
+}
+
+// CHECK: @g = external global %struct.T, align 4
+// CHECK: %{{.*}} = load i64, i64* bitcast (%struct.T* @g to i64*), align 4

Propchange: cfe/trunk/test/CodeGen/arm-bitfield-alignment.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/CodeGen/arm-bitfield-alignment.c
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id





More information about the cfe-commits mailing list