[SystemZ][z/OS] Ignore leading zero width bitfield alignment on z/OS target

Zero length bitfield alignment is not respected if they are leading members on z/OS target.

Reviewed By: abhina.sreeskantharajan

Differential Revision: https://reviews.llvm.org/D98890
This commit is contained in:
Fanbo Meng 2021-03-26 10:09:57 -04:00
parent a26312f9d4
commit 6f91cf75d7
5 changed files with 52 additions and 6 deletions

View File

@ -155,6 +155,10 @@ protected:
/// zero-length bitfield.
unsigned UseZeroLengthBitfieldAlignment : 1;
/// Whether zero length bitfield alignment is respected if they are the
/// leading members.
unsigned UseLeadingZeroLengthBitfield : 1;
/// Whether explicit bit field alignment attributes are honored.
unsigned UseExplicitBitFieldAlignment : 1;
@ -768,6 +772,12 @@ public:
return UseZeroLengthBitfieldAlignment;
}
/// Check whether zero length bitfield alignment is respected if they are
/// leading members.
bool useLeadingZeroLengthBitfield() const {
return UseLeadingZeroLengthBitfield;
}
/// Get the fixed alignment value in bits for a member that follows
/// a zero length bitfield.
unsigned getZeroLengthBitfieldBoundary() const {

View File

@ -1627,12 +1627,17 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
// Some such targets do honor it on zero-width bitfields.
if (FieldSize == 0 &&
Context.getTargetInfo().useZeroLengthBitfieldAlignment()) {
// The alignment to round up to is the max of the field's natural
// alignment and a target-specific fixed value (sometimes zero).
unsigned ZeroLengthBitfieldBoundary =
Context.getTargetInfo().getZeroLengthBitfieldBoundary();
FieldAlign = std::max(FieldAlign, ZeroLengthBitfieldBoundary);
// Some targets don't honor leading zero-width bitfield.
if (!IsUnion && FieldOffset == 0 &&
!Context.getTargetInfo().useLeadingZeroLengthBitfield())
FieldAlign = 1;
else {
// The alignment to round up to is the max of the field's natural
// alignment and a target-specific fixed value (sometimes zero).
unsigned ZeroLengthBitfieldBoundary =
Context.getTargetInfo().getZeroLengthBitfieldBoundary();
FieldAlign = std::max(FieldAlign, ZeroLengthBitfieldBoundary);
}
// If that doesn't apply, just ignore the field alignment.
} else {
FieldAlign = 1;

View File

@ -104,6 +104,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
UseSignedCharForObjCBool = true;
UseBitFieldTypeAlignment = true;
UseZeroLengthBitfieldAlignment = false;
UseLeadingZeroLengthBitfield = true;
UseExplicitBitFieldAlignment = true;
ZeroLengthBitfieldBoundary = 0;
HalfFormat = &llvm::APFloat::IEEEhalf();

View File

@ -796,6 +796,7 @@ public:
this->WCharType = TargetInfo::UnsignedInt;
this->UseBitFieldTypeAlignment = false;
this->UseZeroLengthBitfieldAlignment = true;
this->UseLeadingZeroLengthBitfield = false;
this->ZeroLengthBitfieldBoundary = 32;
this->MinGlobalAlign = 0;
this->DefaultAlignForAttributeAligned = 128;

View File

@ -83,6 +83,35 @@ struct s6 {
// CHECK-NEXT: 8 | char *[] b
// CHECK-NEXT: | [sizeof=8, align=8]
struct s7 {
long :0;
short a;
} S7;
// CHECK: 0 | struct s7
// CHECK-NEXT: 0:- | long
// CHECK-NEXT: 0 | short a
// CHECK-NEXT: | [sizeof=2, align=2]
#pragma pack(2)
struct s8 {
unsigned long :0;
long long a;
} S8;
#pragma pack()
// CHECK: 0 | struct s8
// CHECK-NEXT: 0:- | unsigned long
// CHECK-NEXT: 0 | long long a
// CHECK-NEXT: | [sizeof=8, align=2]
struct s9 {
unsigned int :0;
unsigned short :0;
} S9;
// CHECK: 0 | struct s9
// CHECK-NEXT: 0:- | unsigned int
// CHECK-NEXT: 0:- | unsigned short
// CHECK-NEXT: | [sizeof=0, align=1]
struct s10 {
unsigned int __attribute__((aligned)) a;
} S10;