]> granicus.if.org Git - clang/commitdiff
IRgen: Set alignment correctly on bit-field accesses.
authorDaniel Dunbar <daniel@zuster.org>
Thu, 22 Apr 2010 03:17:04 +0000 (03:17 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 22 Apr 2010 03:17:04 +0000 (03:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102046 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGRecordLayoutBuilder.cpp
test/CodeGen/bitfield-2.c

index 530a41c3d62a1890365ed3d2a1a889e89400f149..17c5640c643aa76a4a9d19ded3c1a23974ee0728 100644 (file)
@@ -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;
 
index 7df4da9da9edaf0a88bc8638ee3ff39034fc62ab..7d6979a542c32fa8d40b4300828dbc5549a96db0 100644 (file)
@@ -17,9 +17,9 @@
 // CHECK-RECORD:     <CGBitFieldInfo Size:24 IsSigned:1
 // CHECK-RECORD:                     NumComponents:2 Components: [
 // CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:16
-// CHECK-RECORD:                     AccessAlignment:0 TargetBitOffset:0 TargetBitWidth:16>
+// CHECK-RECORD:                     AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:16>
 // CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:2 FieldBitStart:0 AccessWidth:8
-// CHECK-RECORD:                     AccessAlignment:0 TargetBitOffset:16 TargetBitWidth:8>
+// 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:     <CGBitFieldInfo Size:10 IsSigned:1
 // CHECK-RECORD:                     NumComponents:1 Components: [
 // CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:16
-// CHECK-RECORD:                     AccessAlignment:0 TargetBitOffset:0 TargetBitWidth:10>
+// CHECK-RECORD:                     AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:10>
 // CHECK-RECORD:     ]>
 // CHECK-RECORD:     <CGBitFieldInfo Size:10 IsSigned:1
 // CHECK-RECORD:                     NumComponents:2 Components: [
 // CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:10 AccessWidth:16
-// CHECK-RECORD:                     AccessAlignment:0 TargetBitOffset:0 TargetBitWidth:6>
+// CHECK-RECORD:                     AccessAlignment:1 TargetBitOffset:0 TargetBitWidth:6>
 // CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:2 FieldBitStart:0 AccessWidth:8
-// CHECK-RECORD:                     AccessAlignment:0 TargetBitOffset:6 TargetBitWidth:4>
+// 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:     <CGBitFieldInfo Size:3 IsSigned:0
 // CHECK-RECORD:                     NumComponents:1 Components: [
 // CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:0 FieldBitStart:0 AccessWidth:8
-// CHECK-RECORD:                     AccessAlignment:0 TargetBitOffset:0 TargetBitWidth:3>
+// 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: <CGRecordLayout
+// CHECK-RECORD:   LLVMType:{ i32, i32, i32, i8, [3 x i8], [4 x i8], [12 x i8] }
+// CHECK-RECORD:   ContainsPointerToDataMember:0
+// CHECK-RECORD:   BitFields:[
+// CHECK-RECORD:     <CGBitFieldInfo Size:5 IsSigned:1
+// CHECK-RECORD:                     NumComponents:1 Components: [
+// CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:12 FieldBitStart:0 AccessWidth:32
+// CHECK-RECORD:                     AccessAlignment:4 TargetBitOffset:0 TargetBitWidth:5>
+// CHECK-RECORD:     ]>
+// CHECK-RECORD:     <CGBitFieldInfo Size:29 IsSigned:1
+// CHECK-RECORD:                     NumComponents:1 Components: [
+// CHECK-RECORD:         <AccessInfo FieldIndex:0 FieldByteOffset:16 FieldBitStart:0 AccessWidth:32
+// CHECK-RECORD:                     AccessAlignment:16 TargetBitOffset:0 TargetBitWidth:29>
+
+struct __attribute__((aligned(16))) s7 {
+  int a, b, c;
+  int f0 : 5;
+  int f1 : 29;
+};
+
+int f7_load(struct s7 *a0) {
+  return a0->f0;
+}