diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4627efc3165..2409e7f59a1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-01-22 Richard Earnshaw + + PR target/88469 + * config/arm/arm.c (arm_needs_doubleword_align): Return 2 if a record's + alignment is dominated by a bitfield with 64-bit aligned base type. + (arm_function_arg): Emit a warning if the alignment has changed since + earlier GCC releases. + (arm_function_arg_boundary): Likewise. + (arm_setup_incoming_varargs): Likewise. + 2019-01-22 Richard Biener PR tree-optimization/88862 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 73cb8df9af1..c6fbda25e96 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -6598,7 +6598,9 @@ arm_init_cumulative_args (CUMULATIVE_ARGS *pcum, tree fntype, } } -/* Return 1 if double word alignment is required for argument passing. +/* Return 2 if double word alignment is required for argument passing, + but wasn't required before the fix for PR88469. + Return 1 if double word alignment is required for argument passing. Return -1 if double word alignment used to be required for argument passing before PR77728 ABI fix, but is not required anymore. Return 0 if double word alignment is not required and wasn't requried @@ -6618,7 +6620,8 @@ arm_needs_doubleword_align (machine_mode mode, const_tree type) return TYPE_ALIGN (TREE_TYPE (type)) > PARM_BOUNDARY; int ret = 0; - /* Record/aggregate types: Use greatest member alignment of any member. */ + int ret2 = 0; + /* Record/aggregate types: Use greatest member alignment of any member. */ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) if (DECL_ALIGN (field) > PARM_BOUNDARY) { @@ -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; return ret; } @@ -6695,7 +6705,12 @@ arm_function_arg (cumulative_args_t pcum_v, machine_mode mode, inform (input_location, "parameter passing for argument of type " "%qT changed in GCC 7.1", type); else if (res > 0) - pcum->nregs++; + { + pcum->nregs++; + if (res > 1 && warn_psabi) + inform (input_location, "parameter passing for argument of type " + "%qT changed in GCC 9.1", type); + } } /* Only allow splitting an arg between regs and memory if all preceding @@ -6722,6 +6737,9 @@ arm_function_arg_boundary (machine_mode mode, const_tree type) if (res < 0 && warn_psabi) inform (input_location, "parameter passing for argument of type %qT " "changed in GCC 7.1", type); + if (res > 1 && warn_psabi) + inform (input_location, "parameter passing for argument of type " + "%qT changed in GCC 9.1", type); return res > 0 ? DOUBLEWORD_ALIGNMENT : PARM_BOUNDARY; } @@ -26999,7 +27017,13 @@ arm_setup_incoming_varargs (cumulative_args_t pcum_v, inform (input_location, "parameter passing for argument of " "type %qT changed in GCC 7.1", type); else if (res > 0) - nregs++; + { + nregs++; + if (res > 1 && warn_psabi) + inform (input_location, + "parameter passing for argument of type " + "%qT changed in GCC 9.1", type); + } } } else diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1b61a3d8803..50705fe6bb0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2019-01-22 Richard Earnshaw + + PR target/88469 + * gcc.target/arm/aapcs/bitfield1.c: New test. + * gcc.target/arm/aapcs/overalign_rec1.c: New test. + * gcc.target/arm/aapcs/overalign_rec2.c: New test. + * gcc.target/arm/aapcs/overalign_rec3.c: New test. + 2019-01-22 Manfred Schwarb * gfortran.dg/array_function_5.f90: Fix a dg directive. diff --git a/gcc/testsuite/gcc.target/arm/aapcs/bitfield1.c b/gcc/testsuite/gcc.target/arm/aapcs/bitfield1.c new file mode 100644 index 00000000000..cac786eec37 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/bitfield1.c @@ -0,0 +1,24 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O" } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "bitfield1.c" + +struct bf +{ + unsigned long long a: 61; + unsigned b: 3; +} 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/overalign_rec1.c b/gcc/testsuite/gcc.target/arm/aapcs/overalign_rec1.c new file mode 100644 index 00000000000..1d33da42bdf --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/overalign_rec1.c @@ -0,0 +1,27 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O" } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "overalign_rec1.c" + +typedef struct __attribute__((aligned(8))) +{ + int a; + int b; +} overaligned; + +overaligned v = {1, 3}; +overaligned w = {33, 99}; + +#include "abitest.h" +#else + ARG (int, 7, R0) + /* Overalignment is ignored for the purposes of parameter passing. */ + ARG (overaligned, v, R1) + ARG (int, 11, R3) + ARG (int, 9, STACK) + LAST_ARG (overaligned, w, STACK+4) +#endif diff --git a/gcc/testsuite/gcc.target/arm/aapcs/overalign_rec2.c b/gcc/testsuite/gcc.target/arm/aapcs/overalign_rec2.c new file mode 100644 index 00000000000..b19fa70c591 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/overalign_rec2.c @@ -0,0 +1,25 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O" } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "overalign_rec2.c" + +typedef struct +{ + int __attribute__((aligned(8))) a; + int b; +} overaligned; + +overaligned v = {1, 3}; +overaligned w = {33, 99}; + +#include "abitest.h" +#else + ARG (int, 7, R0) + ARG (overaligned, v, R2) + ARG (int, 9, STACK) + LAST_ARG (overaligned, w, STACK+8) +#endif diff --git a/gcc/testsuite/gcc.target/arm/aapcs/overalign_rec3.c b/gcc/testsuite/gcc.target/arm/aapcs/overalign_rec3.c new file mode 100644 index 00000000000..b1c793e04e6 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/aapcs/overalign_rec3.c @@ -0,0 +1,28 @@ +/* Test AAPCS layout (alignment). */ + +/* { dg-do run { target arm_eabi } } */ +/* { dg-require-effective-target arm32 } */ +/* { dg-options "-O" } */ + +#ifndef IN_FRAMEWORK +#define TESTFILE "overalign_rec3.c" + +typedef struct +{ + int __attribute__((aligned(16))) a; + int b; +} overaligned; + +overaligned v = {1, 3}; +overaligned w = {33, 99}; + +#include "abitest.h" +#else + ARG (int, 7, R0) + /* Objects with alignment > 8 are passed with alignment 8. */ + ARG (overaligned, v, R2) + ARG (int, 9, STACK+8) + ARG (int, 10, STACK+12) + ARG (int, 11, STACK+16) + LAST_ARG (overaligned, w, STACK+24) +#endif