From: Daniel Dunbar Date: Thu, 22 Apr 2010 16:14:54 +0000 (+0000) Subject: ARM/APCS: Don't respect bit-field types when laying out structures. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=684de63867fac4ffe2f4c97756a16bfcb2d8b54b;p=clang ARM/APCS: Don't respect bit-field types when laying out structures. - This fixes the last known ABI issues with ARM/APCS. - I've run the first 1k ABITests with '--no-unsigned --no-vector --no-complex' on {armv6, armv7} x {-mno-thumb, -mthumb}, and the first 10k tests for armv7 -mthumb, for both function return types and single argument calls. These all pass now (they failed horribly before without --no-bitfield). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102070 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index b94f55bdfd..6624ed9d38 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -1418,6 +1418,10 @@ public: DoubleAlign = LongLongAlign = LongDoubleAlign = 32; SizeType = UnsignedLong; + // Do not respect the alignment of bit-field types when laying out + // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc. + UseBitFieldTypeAlignment = false; + if (IsThumb) { DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-" "i64:32:32-f32:32:32-f64:32:32-" diff --git a/test/CodeGen/arm-arguments.c b/test/CodeGen/arm-arguments.c index cc5af89a6a..72fd7c3f8b 100644 --- a/test/CodeGen/arm-arguments.c +++ b/test/CodeGen/arm-arguments.c @@ -115,7 +115,7 @@ struct s19 f19(void) {} struct s20 { struct s8 f1; int f0; }; struct s20 f20(void) {} -// APCS-GNU: define arm_apcscc i32 @f21() +// APCS-GNU: define arm_apcscc i8 @f21() // AAPCS: define arm_aapcscc i32 @f21() struct s21 { struct {} f1; int f0 : 4; }; struct s21 f21(void) {} diff --git a/test/Sema/arm-layout.c b/test/Sema/arm-layout.c index 1e239d275a..4248685104 100644 --- a/test/Sema/arm-layout.c +++ b/test/Sema/arm-layout.c @@ -1,20 +1,53 @@ // RUN: %clang_cc1 -triple armv7-unknown-unknown -target-abi apcs-gnu %s -verify // RUN: %clang_cc1 -triple armv7-unknown-unknown -target-abi aapcs %s -verify -#ifdef __ARM_EABI__ +#define check(name, cond) int _##name##_check[(cond) ? 1 : -1] struct s0 { char field0; double field1; }; -int g0[sizeof(struct s0) == 16 ? 1 : -1]; +#ifdef __ARM_EABI__ +check(s0_size, sizeof(struct s0) == 16); +#else +check(s0_size, sizeof(struct s0) == 12); +#endif struct s1 { char field0; long double field1; }; -int g1[sizeof(struct s1) == 16 ? 1 : -1]; - +#ifdef __ARM_EABI__ +check(s1_size, sizeof(struct s1) == 16); #else +check(s1_size, sizeof(struct s1) == 12); +#endif -struct s0 { char field0; double field1; }; -int g0[sizeof(struct s0) == 12 ? 1 : -1]; +struct s2 { + short field0; + int field1 : 24; + char field2; +}; +#ifdef __ARM_EABI__ +check(s2_size, sizeof(struct s2) == 8); +check(s2_offset_0, __builtin_offsetof(struct s2, field0) == 0); +check(s2_offset_1, __builtin_offsetof(struct s2, field2) == 7); +#else +check(s2_size, sizeof(struct s2) == 6); +check(s2_offset_0, __builtin_offsetof(struct s2, field0) == 0); +check(s2_offset_1, __builtin_offsetof(struct s2, field2) == 5); +#endif -struct s1 { char field0; long double field1; }; -int g1[sizeof(struct s1) == 12 ? 1 : -1]; +struct s3 { + short field0; + int field1 : 24 __attribute__((aligned(4))); + char field2; +}; +check(s3_size, sizeof(struct s3) == 8); +check(s3_offset_0, __builtin_offsetof(struct s3, field0) == 0); +check(s3_offset_1, __builtin_offsetof(struct s3, field2) == 7); +struct s4 { + int field0 : 4 +}; +#ifdef __ARM_EABI__ +check(s4_size, sizeof(struct s4) == 4); +check(s4_align, __alignof(struct s4) == 4); +#else +check(s4_size, sizeof(struct s4) == 1); +check(s4_align, __alignof(struct s4) == 1); #endif