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.

This patch feels like a bit of a hack to me, but honestly I'm not sure how else 
to go about making this change. This patch is a first attempt to address the 
problem described in the thread 
http://lists.cs.uiuc.edu/pipermail/cfe-dev/2015-April/042521.html.

(There is no testcase attached to this just yet I shall add one tomorrow, I 
just wanted to get this out for review early to see whether I'm approaching 
this the right way).

REPOSITORY
  rL LLVM

http://reviews.llvm.org/D9297

Files:
  lib/CodeGen/CodeGenModule.cpp

Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1799,6 +1799,29 @@
         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.
+    llvm::Triple::ArchType Arch = 
Context.getTargetInfo().getTriple().getArch();
+    if (   Arch == llvm::Triple::arm
+        || Arch == llvm::Triple::armeb
+        || Arch == llvm::Triple::thumb
+        || Arch == llvm::Triple::thumbeb
+        || Arch == llvm::Triple::aarch64
+        || Arch == llvm::Triple::aarch64_be) {
+      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())

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -1799,6 +1799,29 @@
         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.
+    llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch();
+    if (   Arch == llvm::Triple::arm
+        || Arch == llvm::Triple::armeb
+        || Arch == llvm::Triple::thumb
+        || Arch == llvm::Triple::thumbeb
+        || Arch == llvm::Triple::aarch64
+        || Arch == llvm::Triple::aarch64_be) {
+      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())
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to