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.
This commit is contained in:
parent
4a1493f060
commit
49813aad32
|
@ -6337,9 +6337,9 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode,
|
||||||
|
|
||||||
static unsigned int
|
static unsigned int
|
||||||
aarch64_function_arg_alignment (machine_mode mode, const_tree type,
|
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)
|
if (!type)
|
||||||
return GET_MODE_ALIGNMENT (mode);
|
return GET_MODE_ALIGNMENT (mode);
|
||||||
|
|
||||||
|
@ -6381,7 +6381,7 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type,
|
||||||
|
|
||||||
if (bitfield_alignment > alignment)
|
if (bitfield_alignment > alignment)
|
||||||
{
|
{
|
||||||
*abi_break = true;
|
*abi_break = alignment;
|
||||||
return bitfield_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;
|
int ncrn, nvrn, nregs;
|
||||||
bool allocate_ncrn, allocate_nvrn;
|
bool allocate_ncrn, allocate_nvrn;
|
||||||
HOST_WIDE_INT size;
|
HOST_WIDE_INT size;
|
||||||
bool abi_break;
|
unsigned int abi_break;
|
||||||
|
|
||||||
/* We need to do this once per argument. */
|
/* We need to do this once per argument. */
|
||||||
if (pcum->aapcs_arg_processed)
|
if (pcum->aapcs_arg_processed)
|
||||||
|
@ -6721,14 +6721,19 @@ aarch64_function_arg_regno_p (unsigned regno)
|
||||||
static unsigned int
|
static unsigned int
|
||||||
aarch64_function_arg_boundary (machine_mode mode, const_tree type)
|
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,
|
unsigned int alignment = aarch64_function_arg_alignment (mode, type,
|
||||||
&abi_break);
|
&abi_break);
|
||||||
|
alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY);
|
||||||
if (abi_break & warn_psabi)
|
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. */
|
/* 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);
|
f_stack, NULL_TREE);
|
||||||
size = int_size_in_bytes (type);
|
size = int_size_in_bytes (type);
|
||||||
|
|
||||||
bool abi_break;
|
unsigned int abi_break;
|
||||||
align
|
align
|
||||||
= aarch64_function_arg_alignment (mode, type, &abi_break) / BITS_PER_UNIT;
|
= aarch64_function_arg_alignment (mode, type, &abi_break) / BITS_PER_UNIT;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue