Sunil_Srivastava updated this revision to Diff 47026. Sunil_Srivastava added a comment.
Changed the patch based of feedback from John McCall. There is new bit UseExplicitBitFieldAlignment, which is set for everything except for PS4. The r257462 change has been made conditional on this bit. http://reviews.llvm.org/D16788 Files: include/clang/Basic/TargetInfo.h lib/AST/RecordLayoutBuilder.cpp lib/Basic/TargetInfo.cpp lib/Basic/Targets.cpp test/Sema/bitfield-layout.c
Index: test/Sema/bitfield-layout.c =================================================================== --- test/Sema/bitfield-layout.c +++ 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 <stddef.h> @@ -96,9 +97,15 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 { Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -606,6 +606,10 @@ 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: Index: lib/Basic/TargetInfo.cpp =================================================================== --- lib/Basic/TargetInfo.cpp +++ lib/Basic/TargetInfo.cpp @@ -66,6 +66,7 @@ UseSignedCharForObjCBool = true; UseBitFieldTypeAlignment = true; UseZeroLengthBitfieldAlignment = false; + UseExplicitBitFieldAlignment = true; ZeroLengthBitfieldBoundary = 0; HalfFormat = &llvm::APFloat::IEEEhalf; FloatFormat = &llvm::APFloat::IEEEsingle; Index: lib/AST/RecordLayoutBuilder.cpp =================================================================== --- lib/AST/RecordLayoutBuilder.cpp +++ lib/AST/RecordLayoutBuilder.cpp @@ -1600,7 +1600,8 @@ (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 @@ (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize)) UnpackedFieldOffset = llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign); - else if (ExplicitFieldAlign) + else if (ExplicitFieldAlign && + Context.getTargetInfo().useExplicitBitFieldAlignment()) UnpackedFieldOffset = llvm::alignTo(UnpackedFieldOffset, ExplicitFieldAlign); } Index: include/clang/Basic/TargetInfo.h =================================================================== --- include/clang/Basic/TargetInfo.h +++ include/clang/Basic/TargetInfo.h @@ -202,6 +202,9 @@ /// zero-length bitfield. unsigned UseZeroLengthBitfieldAlignment : 1; + /// \brief Whether explicit bit field alignment attributes are honored. + unsigned int 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 @@ 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;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits