Skip to content

Commit

Permalink
[SystemZ][z/OS] Ignore leading zero width bitfield alignment on z/OS …
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
fanbo-meng committed Mar 26, 2021
1 parent a26312f commit 6f91cf7
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 6 deletions.
10 changes: 10 additions & 0 deletions clang/include/clang/Basic/TargetInfo.h
Expand Up @@ -155,6 +155,10 @@ struct TransferrableTargetInfo {
/// 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;

Expand Down Expand Up @@ -768,6 +772,12 @@ class TargetInfo : public virtual TransferrableTargetInfo,
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 {
Expand Down
17 changes: 11 additions & 6 deletions clang/lib/AST/RecordLayoutBuilder.cpp
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/TargetInfo.cpp
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/OSTargets.h
Expand Up @@ -796,6 +796,7 @@ class LLVM_LIBRARY_VISIBILITY ZOSTargetInfo : public OSTargetInfo<Target> {
this->WCharType = TargetInfo::UnsignedInt;
this->UseBitFieldTypeAlignment = false;
this->UseZeroLengthBitfieldAlignment = true;
this->UseLeadingZeroLengthBitfield = false;
this->ZeroLengthBitfieldBoundary = 32;
this->MinGlobalAlign = 0;
this->DefaultAlignForAttributeAligned = 128;
Expand Down
29 changes: 29 additions & 0 deletions clang/test/CodeGen/SystemZ/zos-alignment.c
Expand Up @@ -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;
Expand Down

0 comments on commit 6f91cf7

Please sign in to comment.