diff options
author | Jakub Jelinek <jakub@redhat.com> | 2021-04-16 20:49:33 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2021-04-16 20:49:33 +0200 |
commit | 49813aad3292f7f2bef69206274da78a9a7116ed (patch) | |
tree | a539db71a7c6c3444101ad4372dd2a48f6788f0d /gcc | |
parent | 4a1493f0603262a7dc1114d9827353e9810e63dc (diff) | |
download | gcc-49813aad3292f7f2bef69206274da78a9a7116ed.zip gcc-49813aad3292f7f2bef69206274da78a9a7116ed.tar.gz gcc-49813aad3292f7f2bef69206274da78a9a7116ed.tar.bz2 |
aarch64: Don't emit -Wpsabi note when ABI was never affected [PR91710]
As the following testcase shows, we emit a -Wpsabi note about argument
passing change since GCC 9, but in reality the ABI didn't change.
The alignment is 8 bits in GCC < 9 and 32 bits in GCC >= 9 and
the aarch64_function_arg_alignment returns in that case:
return MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
so when both the old and new alignment are smaller or equal to PARM_BOUNDARY
(or both are larger than STACK_BOUNDARY, just in theory), even when the new
one is bigger, it doesn't change the argument passing.
So, the following patch changes aarch64_function_arg_alignment to tell the
callers the exact old alignmentm so that they can test it if needed.
The other aarch64_function_arg_alignment callers either check the
alignment for equality against 16-byte alignment (when old alignment was
smaller than that and the new one is 16-byte, we want to emit -Wpsabi
in all the cases) or the va_arg case which I think is ok now too.
2021-04-16 Jakub Jelinek <jakub@redhat.com>
PR target/91710
* config/aarch64/aarch64.c (aarch64_function_arg_alignment): Change
abi_break argument from bool * to unsigned *, store there the pre-GCC 9
alignment.
(aarch64_layout_arg, aarch64_gimplify_va_arg_expr): Adjust callers.
(aarch64_function_arg_regno_p): Likewise. Only emit -Wpsabi note if
the old and new alignment after applying MIN/MAX to it is different.
* gcc.target/aarch64/pr91710.c: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 23 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/aarch64/pr91710.c | 16 |
2 files changed, 30 insertions, 9 deletions
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index 09d79f6..12625a4 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -6337,9 +6337,9 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode, static unsigned int aarch64_function_arg_alignment (machine_mode mode, const_tree type, - bool *abi_break) + unsigned int *abi_break) { - *abi_break = false; + *abi_break = 0; if (!type) return GET_MODE_ALIGNMENT (mode); @@ -6381,7 +6381,7 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type, if (bitfield_alignment > alignment) { - *abi_break = true; + *abi_break = alignment; return bitfield_alignment; } @@ -6403,7 +6403,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) int ncrn, nvrn, nregs; bool allocate_ncrn, allocate_nvrn; HOST_WIDE_INT size; - bool abi_break; + unsigned int abi_break; /* We need to do this once per argument. */ if (pcum->aapcs_arg_processed) @@ -6721,14 +6721,19 @@ aarch64_function_arg_regno_p (unsigned regno) static unsigned int aarch64_function_arg_boundary (machine_mode mode, const_tree type) { - bool abi_break; + unsigned int abi_break; unsigned int alignment = aarch64_function_arg_alignment (mode, type, &abi_break); + alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); if (abi_break & warn_psabi) - inform (input_location, "parameter passing for argument of type " - "%qT changed in GCC 9.1", type); + { + abi_break = MIN (MAX (abi_break, PARM_BOUNDARY), STACK_BOUNDARY); + if (alignment != abi_break) + inform (input_location, "parameter passing for argument of type " + "%qT changed in GCC 9.1", type); + } - return MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); + return alignment; } /* Implement TARGET_GET_RAW_RESULT_MODE and TARGET_GET_RAW_ARG_MODE. */ @@ -18253,7 +18258,7 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, f_stack, NULL_TREE); size = int_size_in_bytes (type); - bool abi_break; + unsigned int abi_break; align = aarch64_function_arg_alignment (mode, type, &abi_break) / BITS_PER_UNIT; diff --git a/gcc/testsuite/gcc.target/aarch64/pr91710.c b/gcc/testsuite/gcc.target/aarch64/pr91710.c new file mode 100644 index 0000000..496eb50 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr91710.c @@ -0,0 +1,16 @@ +/* PR target/91710 */ +/* { dg-do compile } */ + +struct S { unsigned int i:4; }; + +unsigned int test1(struct S s) { /* { dg-bogus "parameter passing for argument of type" } */ + return s.i; +} + +unsigned int test2(unsigned x, struct S s) { /* { dg-bogus "parameter passing for argument of type" } */ + return x - s.i; +} + +unsigned int test3(unsigned x, unsigned y, struct S s) { /* { dg-bogus "parameter passing for argument of type" } */ + return x - y - s.i; +} |