2021-03-18 Jakub Jelinek 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. --- gcc/config/aarch64/aarch64.c.jj 2021-03-18 15:14:51.721425223 +0100 +++ gcc/config/aarch64/aarch64.c 2021-03-18 16:35:04.437115447 +0100 @@ -5938,9 +5938,9 @@ aarch64_vfp_is_call_candidate (cumulativ 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); @@ -5982,7 +5982,7 @@ aarch64_function_arg_alignment (machine_ if (bitfield_alignment > alignment) { - *abi_break = true; + *abi_break = alignment; return bitfield_alignment; } @@ -6004,7 +6004,7 @@ aarch64_layout_arg (cumulative_args_t pc 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) @@ -6322,14 +6322,19 @@ aarch64_function_arg_regno_p (unsigned r 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. */ @@ -16616,7 +16621,7 @@ aarch64_gimplify_va_arg_expr (tree valis 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; --- gcc/testsuite/gcc.target/aarch64/pr91710.c.jj 2021-03-18 16:42:33.529232710 +0100 +++ gcc/testsuite/gcc.target/aarch64/pr91710.c 2021-03-18 16:42:07.271518121 +0100 @@ -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; +}