From 4cff2fd9cc3b258df7f195ff3b30fbc8dde39b43 Mon Sep 17 00:00:00 2001 From: Sunil Srivastava Date: Fri, 5 Feb 2016 20:50:02 +0000 Subject: [PATCH] Do not honor explicit alignment attribute on fields for PS4. This change reverts r257462 for PS4 triple. Differential Revision: http://reviews.llvm.org/D16788 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@259916 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/TargetInfo.h | 9 ++++++++ lib/AST/RecordLayoutBuilder.cpp | 6 +++-- lib/Basic/TargetInfo.cpp | 1 + lib/Basic/Targets.cpp | 4 ++++ test/Sema/bitfield-layout.c | 38 +++++++++++++++++++++++++++++++- 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 69aab0ef8c..dd5039898d 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -202,6 +202,9 @@ protected: /// zero-length bitfield. unsigned UseZeroLengthBitfieldAlignment : 1; + /// \brief Whether explicit bit field alignment attributes are honored. + unsigned UseExplicitBitFieldAlignment : 1; + /// If non-zero, specifies a fixed alignment value for bitfields that follow /// zero length bitfield, regardless of the zero length bitfield type. unsigned ZeroLengthBitfieldBoundary; @@ -466,6 +469,12 @@ public: return ZeroLengthBitfieldBoundary; } + /// \brief Check whether explicit bitfield alignment attributes should be + // honored, as in "__attribute__((aligned(2))) int b : 1;". + bool useExplicitBitFieldAlignment() const { + return UseExplicitBitFieldAlignment; + } + /// \brief Check whether this target support '\#pragma options align=mac68k'. bool hasAlignMac68kSupport() const { return HasAlignMac68kSupport; diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp index 0572ff6b13..b8891cb388 100644 --- a/lib/AST/RecordLayoutBuilder.cpp +++ b/lib/AST/RecordLayoutBuilder.cpp @@ -1600,7 +1600,8 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { (AllowPadding && (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)) { FieldOffset = llvm::alignTo(FieldOffset, FieldAlign); - } else if (ExplicitFieldAlign) { + } else if (ExplicitFieldAlign && + Context.getTargetInfo().useExplicitBitFieldAlignment()) { // TODO: figure it out what needs to be done on targets that don't honor // bit-field type alignment like ARM APCS ABI. FieldOffset = llvm::alignTo(FieldOffset, ExplicitFieldAlign); @@ -1612,7 +1613,8 @@ void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize)) UnpackedFieldOffset = llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign); - else if (ExplicitFieldAlign) + else if (ExplicitFieldAlign && + Context.getTargetInfo().useExplicitBitFieldAlignment()) UnpackedFieldOffset = llvm::alignTo(UnpackedFieldOffset, ExplicitFieldAlign); } diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 1648a27d8b..4a2341e565 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -66,6 +66,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { UseSignedCharForObjCBool = true; UseBitFieldTypeAlignment = true; UseZeroLengthBitfieldAlignment = false; + UseExplicitBitFieldAlignment = true; ZeroLengthBitfieldBoundary = 0; HalfFormat = &llvm::APFloat::IEEEhalf; FloatFormat = &llvm::APFloat::IEEEsingle; diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 1c05eeef84..cbbf51be18 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -606,6 +606,10 @@ public: this->MaxTLSAlign = 256; this->UserLabelPrefix = ""; + // On PS4, do not honor explicit bit field alignment, + // as in "__attribute__((aligned(2))) int b : 1;". + this->UseExplicitBitFieldAlignment = false; + switch (Triple.getArch()) { default: case llvm::Triple::x86_64: diff --git a/test/Sema/bitfield-layout.c b/test/Sema/bitfield-layout.c index 3affa21a36..7b434dddcf 100644 --- a/test/Sema/bitfield-layout.c +++ b/test/Sema/bitfield-layout.c @@ -2,6 +2,7 @@ // RUN: %clang_cc1 %s -fsyntax-only -verify -triple=arm-linux-gnueabihf // RUN: %clang_cc1 %s -fsyntax-only -verify -triple=aarch64-linux-gnu // RUN: %clang_cc1 %s -fsyntax-only -verify -triple=x86_64-pc-linux-gnu +// RUN: %clang_cc1 %s -fsyntax-only -verify -triple=x86_64-scei-ps4 // expected-no-diagnostics #include @@ -96,9 +97,15 @@ struct g0 { char c; }; +#if defined(__PS4__) +CHECK_SIZE(struct, g0, 16); +CHECK_ALIGN(struct, g0, 16); +CHECK_OFFSET(struct, g0, c, 2); +#else CHECK_SIZE(struct, g0, 32); CHECK_ALIGN(struct, g0, 16); CHECK_OFFSET(struct, g0, c, 17); +#endif // Bit-field with explicit align smaller than normal. struct g1 { @@ -109,7 +116,11 @@ struct g1 { CHECK_SIZE(struct, g1, 4); CHECK_ALIGN(struct, g1, 4); +#if defined(__PS4__) +CHECK_OFFSET(struct, g1, c, 2); +#else CHECK_OFFSET(struct, g1, c, 3); +#endif // Same as above but without explicit align. struct g2 { @@ -130,9 +141,14 @@ struct __attribute__((packed)) g3 { char c; }; -CHECK_SIZE(struct, g3, 32); CHECK_ALIGN(struct, g3, 16); +#if defined(__PS4__) +CHECK_SIZE(struct, g3, 16); +CHECK_OFFSET(struct, g3, c, 2); +#else +CHECK_SIZE(struct, g3, 32); CHECK_OFFSET(struct, g3, c, 17); +#endif struct __attribute__((packed)) g4 { char a; @@ -142,7 +158,11 @@ struct __attribute__((packed)) g4 { CHECK_SIZE(struct, g4, 4); CHECK_ALIGN(struct, g4, 2); +#if defined(__PS4__) +CHECK_OFFSET(struct, g4, c, 2); +#else CHECK_OFFSET(struct, g4, c, 3); +#endif struct g5 { char : 1; @@ -162,28 +182,44 @@ struct g7 { char : 1; __attribute__((aligned(1))) int n : 25; }; +#if defined(__PS4__) +CHECK_SIZE(struct, g7, 4); +#else CHECK_SIZE(struct, g7, 8); +#endif CHECK_ALIGN(struct, g7, 4); struct __attribute__((packed)) g8 { char : 1; __attribute__((aligned(1))) int n : 25; }; +#if defined(__PS4__) +CHECK_SIZE(struct, g8, 4); +#else CHECK_SIZE(struct, g8, 5); +#endif CHECK_ALIGN(struct, g8, 1); struct g9 { __attribute__((aligned(1))) char a : 2, b : 2, c : 2, d : 2, e : 2; int i; }; +#if defined(__PS4__) +CHECK_SIZE(struct, g9, 8); +#else CHECK_SIZE(struct, g9, 12); +#endif CHECK_ALIGN(struct, g9, 4); struct __attribute__((packed)) g10 { __attribute__((aligned(1))) char a : 2, b : 2, c : 2, d : 2, e : 2; int i; }; +#if defined(__PS4__) +CHECK_SIZE(struct, g10, 6); +#else CHECK_SIZE(struct, g10, 9); +#endif CHECK_ALIGN(struct, g10, 1); struct g11 { -- 2.40.0