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);
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;
// 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;
};
// 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)
// 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;
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;
+}