Skip to content

Commit 75e6e37

Browse files
committed
[AArch64] Allow 128-bit containers for over-sized bitfields
AAPCS64 defines the bitfield layout algorithm for over-sized bitfields as picking a container which is the fundamental integer data type with the largest size less than or equal to the bit-field width. Since AAPCS64 has a 128-bit integer fundamental data type, we need to consider Int128 as a container type for AArch64.
1 parent 223eb6f commit 75e6e37

File tree

6 files changed

+23
-7
lines changed

6 files changed

+23
-7
lines changed

clang/include/clang/Basic/TargetInfo.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ struct TransferrableTargetInfo {
199199
/// zero length bitfield, regardless of the zero length bitfield type.
200200
unsigned ZeroLengthBitfieldBoundary;
201201

202+
/// The largest container size which should be used for an over-sized
203+
/// bitfield, in bits.
204+
unsigned LargestOverSizedBitfieldContainer;
205+
202206
/// If non-zero, specifies a maximum alignment to truncate alignment
203207
/// specified in the aligned attribute of a static variable to this value.
204208
unsigned MaxAlignedAttribute;
@@ -954,6 +958,10 @@ class TargetInfo : public TransferrableTargetInfo,
954958
return ZeroLengthBitfieldBoundary;
955959
}
956960

961+
unsigned getLargestOverSizedBitfieldContainer() const {
962+
return LargestOverSizedBitfieldContainer;
963+
}
964+
957965
/// Get the maximum alignment in bits for a static variable with
958966
/// aligned attribute.
959967
unsigned getMaxAlignedAttribute() const { return MaxAlignedAttribute; }

clang/lib/AST/RecordLayoutBuilder.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,15 +1469,18 @@ void ItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
14691469
// sizeof(T')*8 <= n.
14701470

14711471
QualType IntegralPODTypes[] = {
1472-
Context.UnsignedCharTy, Context.UnsignedShortTy, Context.UnsignedIntTy,
1473-
Context.UnsignedLongTy, Context.UnsignedLongLongTy
1472+
Context.UnsignedCharTy, Context.UnsignedShortTy,
1473+
Context.UnsignedIntTy, Context.UnsignedLongTy,
1474+
Context.UnsignedLongLongTy, Context.UnsignedInt128Ty,
14741475
};
14751476

14761477
QualType Type;
1478+
uint64_t MaxSize =
1479+
Context.getTargetInfo().getLargestOverSizedBitfieldContainer();
14771480
for (const QualType &QT : IntegralPODTypes) {
14781481
uint64_t Size = Context.getTypeSize(QT);
14791482

1480-
if (Size > FieldSize)
1483+
if (Size > FieldSize || Size > MaxSize)
14811484
break;
14821485

14831486
Type = QT;

clang/lib/Basic/TargetInfo.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
141141
UseLeadingZeroLengthBitfield = true;
142142
UseExplicitBitFieldAlignment = true;
143143
ZeroLengthBitfieldBoundary = 0;
144+
LargestOverSizedBitfieldContainer = 64;
144145
MaxAlignedAttribute = 0;
145146
HalfFormat = &llvm::APFloat::IEEEhalf();
146147
FloatFormat = &llvm::APFloat::IEEEsingle();

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,10 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
261261
assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
262262
UseZeroLengthBitfieldAlignment = true;
263263

264+
// AAPCS64 allows any "fundamental integer data type" to be used for
265+
// over-sized bitfields, which includes 128-bit integers.
266+
LargestOverSizedBitfieldContainer = 128;
267+
264268
HasUnalignedAccess = true;
265269

266270
// AArch64 targets default to using the ARM C++ ABI.

clang/test/CodeGen/aapcs64-align.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ extern "C" {
88
// CHECK: @sizeof_OverSizedBitfield ={{.*}} global i32 8
99
// CHECK: @alignof_OverSizedBitfield ={{.*}} global i32 8
1010
// CHECK: @sizeof_VeryOverSizedBitfield ={{.*}} global i32 16
11-
// CHECK: @alignof_VeryOverSizedBitfield ={{.*}} global i32 8
11+
// CHECK: @alignof_VeryOverSizedBitfield ={{.*}} global i32 16
1212
// CHECK: @sizeof_RidiculouslyOverSizedBitfield ={{.*}} global i32 32
13-
// CHECK: @alignof_RidiculouslyOverSizedBitfield ={{.*}} global i32 8
13+
// CHECK: @alignof_RidiculouslyOverSizedBitfield ={{.*}} global i32 16
1414

1515
// Base case, nothing interesting.
1616
struct S {

clang/test/CodeGenCXX/debug-info-structured-binding-bitfield.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,8 @@ struct S15 {
248248
};
249249

250250
// CHECK-LABEL: define dso_local void @_Z4fS15v
251-
// CHECK: alloca %struct.S15, align 8
252-
// CHECK-NEXT: [[TMP0:%.*]] = alloca %struct.S15, align 8
251+
// CHECK: alloca %struct.S15, align 16
252+
// CHECK-NEXT: [[TMP0:%.*]] = alloca %struct.S15, align 16
253253
// CHECK: #dbg_declare(ptr [[TMP0]], [[S15_A:![0-9]+]], !DIExpression(DW_OP_LLVM_extract_bits_sext, 0, 32),
254254
// CHECK-NEXT: #dbg_declare(ptr [[TMP0]], [[S15_B:![0-9]+]], !DIExpression(DW_OP_plus_uconst, 16, DW_OP_LLVM_extract_bits_zext, 0, 32),
255255
//

0 commit comments

Comments
 (0)