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