On 22/01/2019 14:50, Jakub Jelinek wrote:
> On Tue, Jan 22, 2019 at 02:10:59PM +0000, Richard Earnshaw (lists) wrote:
>> @@ -6630,6 +6633,13 @@ arm_needs_doubleword_align (machine_mode mode, 
>> const_tree type)
>>           Make sure we can warn about that with -Wpsabi.  */
>>        ret = -1;
>>        }
>> +    else if (TREE_CODE (field) == FIELD_DECL
>> +         && DECL_BIT_FIELD (field)
>> +         && TYPE_ALIGN (DECL_BIT_FIELD_TYPE (field)) > PARM_BOUNDARY)
>> +      ret2 = 1;
>> +
>> +  if (ret2)
>> +    return 2;
> 
> Can you double check what behavior you want e.g. for:
> typedef int alint __attribute__((aligned (8)));
> struct S1 { alint a : 17; alint b : 15; };
> struct __attribute__((packed)) S2 { char a; long long b : 12; long long c : 
> 20; long long d : 32; };
> struct __attribute__((packed)) S3 { char a; alint b : 12; alint c : 20; };
> and passing/returning of S1/S2/S3?
> TYPE_ALIGN (DECL_BIT_FIELD_TYPE (field)) is I think alint in this case,
> and for packed structures, I guess DECL_ALIGN of the fields is generally
> small, but TYPE_ALIGN might not be.

If TYPE_ALIGN says that we need DWORD alignment then we never look
inside the bitfield, it's only when that is less than 64-bit alignment
that we look deeper.

But Richi pointed out that

int64_t a : 16;

can be internally transformed into a 'short' so we need to look at
DECL_BIT_FIELD_TYPE not at DECL_BIT_FIELD.

I've also added a test for bitfields that are based on overaligned types.

Fixed thusly.

PR target/88469
gcc:
        * config/arm/arm.c (arm_needs_double_word_align): Check
        DECL_BIT_FIELD_TYPE.

gcc/testsuite:
        * gcc.target/arm/aapcs/bitfield2.c: New test.
        * gcc.target/arm/aapcs/bitfield3.c: New test.


> 
>       Jakub
> 

diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index c6fbda25e96..16e22eed871 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -6634,7 +6634,7 @@ arm_needs_doubleword_align (machine_mode mode, const_tree type)
 	  ret = -1;
       }
     else if (TREE_CODE (field) == FIELD_DECL
-	     && DECL_BIT_FIELD (field)
+	     && DECL_BIT_FIELD_TYPE (field)
 	     && TYPE_ALIGN (DECL_BIT_FIELD_TYPE (field)) > PARM_BOUNDARY)
       ret2 = 1;
 
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/bitfield2.c b/gcc/testsuite/gcc.target/arm/aapcs/bitfield2.c
new file mode 100644
index 00000000000..9cbe2b08962
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/aapcs/bitfield2.c
@@ -0,0 +1,26 @@
+/* Test AAPCS layout (alignment).  */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm32 } */
+/* { dg-options "-O" } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "bitfield2.c"
+
+typedef unsigned int alint __attribute__((aligned (8)));
+
+struct bf
+{
+  alint a: 17;
+  alint b: 15;
+} v = {1, 1};
+
+#include "abitest.h"
+#else
+  ARG (int, 7, R0)
+  ARG (int, 9, R1)
+  ARG (int, 11, R2)
+  /* Alignment of the bitfield type should affect alignment of the overall
+     type, so R3 not used.  */
+  LAST_ARG (struct bf, v, STACK)
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/bitfield3.c b/gcc/testsuite/gcc.target/arm/aapcs/bitfield3.c
new file mode 100644
index 00000000000..0386e669c2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/aapcs/bitfield3.c
@@ -0,0 +1,26 @@
+/* Test AAPCS layout (alignment).  */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm32 } */
+/* { dg-options "-O" } */
+
+#ifndef IN_FRAMEWORK
+#define TESTFILE "bitfield3.c"
+
+struct bf
+{
+  /* Internally this may be mapped to unsigned short.  Ensure we still
+     check the original declaration.  */
+  unsigned long long a: 16;
+  unsigned b: 3;
+} v = {1, 3};
+
+#include "abitest.h"
+#else
+  ARG (int, 7, R0)
+  ARG (int, 9, R1)
+  ARG (int, 11, R2)
+  /* Alignment of the bitfield type should affect alignment of the overall
+     type, so R3 not used.  */
+  LAST_ARG (struct bf, v, STACK)
+#endif

Reply via email to