aarch64_function_arg_alignment has two related abi_break parameters: abi_break for a change in GCC 9, and abi_break_packed for a related follow-on change in GCC 13. In a sense, abi_break_packed is a "subfix" of abi_break.
PR109661 now requires a third ABI break that is independent of the other two. Having abi_break for the GCC 9 break and abi_break_<something> for the GCC 13 and GCC 14 breaks might give the impression that they're all related, and that the GCC 14 fix (like the GCC 13 fix) is a "subfix" of the GCC 9 one. It therefore seemed like a good idea to rename the existing variables first. It would be difficult to choose names that describe briefly and precisely what went wrong in each case. The next best thing seemed to be to name them after the relevant GCC version. (Of course, this might break down in future if we need two independent fixes in the same version. Let's hope not.) I wondered about putting all the variables in a structure, but one advantage of using independent variables is that it's harder to forget to update a caller. Maybe a fourth parameter would be a tipping point. Tested on aarch64-linux-gnu & pushed. Richard gcc/ PR target/109661 * config/aarch64/aarch64.cc (aarch64_function_arg_alignment): Rename ABI break variables to abi_break_gcc_9 and abi_break_gcc_13. (aarch64_layout_arg, aarch64_function_arg_boundary): Likewise. (aarch64_gimplify_va_arg_expr): Likewise. --- gcc/config/aarch64/aarch64.cc | 70 ++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index 2b0de7ca038..70916ad63d2 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -7464,19 +7464,20 @@ aarch64_vfp_is_call_candidate (cumulative_args_t pcum_v, machine_mode mode, /* Given MODE and TYPE of a function argument, return the alignment in bits. The idea is to suppress any stronger alignment requested by the user and opt for the natural alignment (specified in AAPCS64 \S - 4.1). ABI_BREAK is set to the old alignment if the alignment was - incorrectly calculated in versions of GCC prior to GCC-9. - ABI_BREAK_PACKED is set to the old alignment if it was incorrectly - calculated in versions between GCC-9 and GCC-13. This is a helper - function for local use only. */ + 4.1). ABI_BREAK_GCC_9 is set to the old alignment if the alignment + was incorrectly calculated in versions of GCC prior to GCC 9. + ABI_BREAK_GCC_13 is set to the old alignment if it was incorrectly + calculated in versions between GCC 9 and GCC 13. + + This is a helper function for local use only. */ static unsigned int aarch64_function_arg_alignment (machine_mode mode, const_tree type, - unsigned int *abi_break, - unsigned int *abi_break_packed) + unsigned int *abi_break_gcc_9, + unsigned int *abi_break_gcc_13) { - *abi_break = 0; - *abi_break_packed = 0; + *abi_break_gcc_9 = 0; + *abi_break_gcc_13 = 0; if (!type) return GET_MODE_ALIGNMENT (mode); @@ -7547,11 +7548,11 @@ aarch64_function_arg_alignment (machine_mode mode, const_tree type, 'packed' attribute into account. */ if (bitfield_alignment != bitfield_alignment_with_packed && bitfield_alignment_with_packed > alignment) - *abi_break_packed = bitfield_alignment_with_packed; + *abi_break_gcc_13 = bitfield_alignment_with_packed; if (bitfield_alignment > alignment) { - *abi_break = alignment; + *abi_break_gcc_9 = alignment; return bitfield_alignment; } @@ -7573,8 +7574,8 @@ 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; - unsigned int abi_break; - unsigned int abi_break_packed; + unsigned int abi_break_gcc_9; + unsigned int abi_break_gcc_13; /* We need to do this once per argument. */ if (pcum->aapcs_arg_processed) @@ -7612,7 +7613,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) Versions prior to GCC 9.1 ignored a bitfield's underlying type and so could calculate an alignment that was too small. If this - happened for TYPE then ABI_BREAK is this older, too-small alignment. + happened for TYPE then ABI_BREAK_GCC_9 is this older, too-small alignment. Although GCC 9.1 fixed that bug, it introduced a different one: it would consider the alignment of a bitfield's underlying type even @@ -7620,7 +7621,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) the alignment of the underlying type). This was fixed in GCC 13.1. As a result of this bug, GCC 9 to GCC 12 could calculate an alignment - that was too big. If this happened for TYPE, ABI_BREAK_PACKED is + that was too big. If this happened for TYPE, ABI_BREAK_GCC_13 is this older, too-big alignment. Also, the fact that GCC 9 to GCC 12 considered irrelevant @@ -7713,12 +7714,12 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) gcc_assert (!sve_p || !allocate_nvrn); unsigned int alignment - = aarch64_function_arg_alignment (mode, type, &abi_break, - &abi_break_packed); + = aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9, + &abi_break_gcc_13); gcc_assert ((allocate_nvrn || alignment <= 16 * BITS_PER_UNIT) - && (!alignment || abi_break < alignment) - && (!abi_break_packed || alignment < abi_break_packed)); + && (!alignment || abi_break_gcc_9 < alignment) + && (!abi_break_gcc_13 || alignment < abi_break_gcc_13)); /* allocate_ncrn may be false-positive, but allocate_nvrn is quite reliable. The following code thus handles passing by SIMD/FP registers first. */ @@ -7792,8 +7793,8 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) /* Emit a warning if the alignment changed when taking the 'packed' attribute into account. */ if (warn_pcs_change - && abi_break_packed - && ((abi_break_packed == 16 * BITS_PER_UNIT) + && abi_break_gcc_13 + && ((abi_break_gcc_13 == 16 * BITS_PER_UNIT) != (alignment == 16 * BITS_PER_UNIT))) inform (input_location, "parameter passing for argument of type " "%qT changed in GCC 13.1", type); @@ -7804,7 +7805,7 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const function_arg_info &arg) passed by reference rather than value. */ if (alignment == 16 * BITS_PER_UNIT) { - if (warn_pcs_change && abi_break) + if (warn_pcs_change && abi_break_gcc_9) inform (input_location, "parameter passing for argument of type " "%qT changed in GCC 9.1", type); ++ncrn; @@ -7863,8 +7864,8 @@ on_stack: pcum->aapcs_stack_words = size / UNITS_PER_WORD; if (warn_pcs_change - && abi_break_packed - && ((abi_break_packed >= 16 * BITS_PER_UNIT) + && abi_break_gcc_13 + && ((abi_break_gcc_13 >= 16 * BITS_PER_UNIT) != (alignment >= 16 * BITS_PER_UNIT))) inform (input_location, "parameter passing for argument of type " "%qT changed in GCC 13.1", type); @@ -7874,7 +7875,7 @@ on_stack: int new_size = ROUND_UP (pcum->aapcs_stack_size, 16 / UNITS_PER_WORD); if (pcum->aapcs_stack_size != new_size) { - if (warn_pcs_change && abi_break) + if (warn_pcs_change && abi_break_gcc_9) inform (input_location, "parameter passing for argument of type " "%qT changed in GCC 9.1", type); pcum->aapcs_stack_size = new_size; @@ -7991,11 +7992,11 @@ aarch64_function_arg_regno_p (unsigned regno) static unsigned int aarch64_function_arg_boundary (machine_mode mode, const_tree type) { - unsigned int abi_break; - unsigned int abi_break_packed; + unsigned int abi_break_gcc_9; + unsigned int abi_break_gcc_13; unsigned int alignment = aarch64_function_arg_alignment (mode, type, - &abi_break, - &abi_break_packed); + &abi_break_gcc_9, + &abi_break_gcc_13); /* We rely on aarch64_layout_arg and aarch64_gimplify_va_arg_expr to emit warnings about ABI incompatibility. */ alignment = MIN (MAX (alignment, PARM_BOUNDARY), STACK_BOUNDARY); @@ -19762,10 +19763,11 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, f_stack, NULL_TREE); size = int_size_in_bytes (type); - unsigned int abi_break; - unsigned int abi_break_packed; + unsigned int abi_break_gcc_9; + unsigned int abi_break_gcc_13; align - = aarch64_function_arg_alignment (mode, type, &abi_break, &abi_break_packed) + = aarch64_function_arg_alignment (mode, type, &abi_break_gcc_9, + &abi_break_gcc_13) / BITS_PER_UNIT; dw_align = false; @@ -19809,13 +19811,13 @@ aarch64_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, rsize = ROUND_UP (size, UNITS_PER_WORD); nregs = rsize / UNITS_PER_WORD; - if (align <= 8 && abi_break_packed && warn_psabi) + if (align <= 8 && abi_break_gcc_13 && warn_psabi) inform (input_location, "parameter passing for argument of type " "%qT changed in GCC 13.1", type); if (align > 8) { - if (abi_break && warn_psabi) + if (abi_break_gcc_9 && warn_psabi) inform (input_location, "parameter passing for argument of type " "%qT changed in GCC 9.1", type); dw_align = true; -- 2.25.1