From: Daniel Dunbar Date: Thu, 22 Apr 2010 03:17:04 +0000 (+0000) Subject: IRgen: Set alignment correctly on bit-field accesses. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=89da874f8ecfebabdac2c6e9b7930ebe179ccf81;p=clang IRgen: Set alignment correctly on bit-field accesses. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102046 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index 530a41c3d6..17c5640c64 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -152,8 +152,9 @@ static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types, uint64_t FieldOffset, uint64_t FieldSize) { const RecordDecl *RD = FD->getParent(); - uint64_t ContainingTypeSizeInBits = - Types.getContext().getASTRecordLayout(RD).getSize(); + const ASTRecordLayout &RL = Types.getContext().getASTRecordLayout(RD); + uint64_t ContainingTypeSizeInBits = RL.getSize(); + unsigned ContainingTypeAlign = RL.getAlignment(); const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(FD->getType()); uint64_t TypeSizeInBytes = Types.getTargetData().getTypeAllocSize(Ty); @@ -223,8 +224,7 @@ static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types, AI.FieldByteOffset = AccessStart / 8; AI.FieldBitStart = AccessBitsInFieldStart - AccessStart; AI.AccessWidth = AccessWidth; - // FIXME: This might be wrong! - AI.AccessAlignment = 0; + AI.AccessAlignment = llvm::MinAlign(ContainingTypeAlign, AccessStart) / 8; AI.TargetBitOffset = AccessedTargetBits; AI.TargetBitWidth = AccessBitsInFieldSize; diff --git a/test/CodeGen/bitfield-2.c b/test/CodeGen/bitfield-2.c index 7df4da9da9..7d6979a542 100644 --- a/test/CodeGen/bitfield-2.c +++ b/test/CodeGen/bitfield-2.c @@ -17,9 +17,9 @@ // CHECK-RECORD: +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:16> // CHECK-RECORD: +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:16 TargetBitWidth:8> struct __attribute((packed)) s0 { int f0 : 24; }; @@ -62,14 +62,14 @@ unsigned long long test_0() { // CHECK-RECORD: +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:10> // CHECK-RECORD: ]> // CHECK-RECORD: +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:6> // CHECK-RECORD: +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:6 TargetBitWidth:4> #pragma pack(push) #pragma pack(1) @@ -119,7 +119,7 @@ unsigned long long test_1() { // CHECK-RECORD: +// CHECK-RECORD: AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:3> union __attribute__((packed)) u2 { unsigned long long f0 : 3; @@ -280,3 +280,33 @@ _Bool test_6() { res ^= g6.f0; return res; } + +/***/ + +// Check that we compute the best alignment possible for each access. +// +// CHECK-RECORD: *** Dumping IRgen Record Layout +// CHECK-RECORD: Record: struct s7 +// CHECK-RECORD: Layout: +// CHECK-RECORD: ]> +// CHECK-RECORD: + +struct __attribute__((aligned(16))) s7 { + int a, b, c; + int f0 : 5; + int f1 : 29; +}; + +int f7_load(struct s7 *a0) { + return a0->f0; +}