Hi all,
This is a fix for the regression I caused with my preserve_none patch.
Bootstrapped and reg tested on aarch64-linux-gnu.
Kind Regards,
Alfie
-- >8 --
When laying out arguments of size 0, previously would return the next argument
passing register, without checking that there was a next one.
This was fine for AAPCS as it used R0-R7 for argument passing and R9 would be
occasionally be assigned, but never used.
However, with the introduction of preserve_none PCS there is no obvious "next
register" to use as aaaa dummy value, and so when laying out in the
"next register" when there were no more, an assert triggered an ICE.
This patch fixes this ICE by instead using NULL_RTX for arguments of size 0.
PR target/122763
gcc/ChangeLog:
* config/aarch64/aarch64.cc (aarch64_layout_arg): Return NULL_RTX for
arguments of size 0.
(aarch64_function_arg_advance): Remove assert.
gcc/testsuite/ChangeLog:
* gcc.target/aarch64/pr122763.c: New test.
---
gcc/config/aarch64/aarch64.cc | 15 ++---
gcc/testsuite/gcc.target/aarch64/pr122763.c | 75 +++++++++++++++++++++
2 files changed, 81 insertions(+), 9 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/aarch64/pr122763.c
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 2e6e468e62b..35013bd28d4 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -7672,11 +7672,11 @@ aarch64_layout_arg (cumulative_args_t pcum_v, const
function_arg_info &arg)
}
/* NREGS can be 0 when e.g. an empty structure is to be passed.
- A reg is still generated for it, but the caller should be smart
- enough not to use it. */
- if (nregs == 0
- || (nregs == 1 && !sve_p)
- || GET_MODE_CLASS (mode) == MODE_INT)
+ In this situation the register should never be used, so assign
+ NULL_RTX. */
+ if (nregs == 0)
+ pcum->aapcs_reg = NULL_RTX;
+ else if ((nregs == 1 && !sve_p) || GET_MODE_CLASS (mode) == MODE_INT)
pcum->aapcs_reg
= gen_rtx_REG (mode, get_pcs_arg_reg (pcum->pcs_variant, ncrn));
else
@@ -7879,10 +7879,7 @@ aarch64_function_arg_advance (cumulative_args_t pcum_v,
|| pcum->pcs_variant == ARM_PCS_PRESERVE_NONE)
{
aarch64_layout_arg (pcum_v, arg);
- gcc_assert ((pcum->aapcs_reg != NULL_RTX)
- != (pcum->aapcs_stack_words != 0));
- if (pcum->aapcs_reg
- && aarch64_call_switches_pstate_sm (pcum->isa_mode))
+ if (pcum->aapcs_reg && aarch64_call_switches_pstate_sm (pcum->isa_mode))
aarch64_record_sme_mode_switch_args (pcum);
pcum->aapcs_arg_processed = false;
diff --git a/gcc/testsuite/gcc.target/aarch64/pr122763.c
b/gcc/testsuite/gcc.target/aarch64/pr122763.c
new file mode 100644
index 00000000000..bd90c665236
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr122763.c
@@ -0,0 +1,75 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu99 " } */
+/* { dg-additional-options "-O -fno-schedule-insns -fno-schedule-insns2 " } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+/* { dg-skip-if "" { *-*-mingw* } } */
+
+typedef struct es {} Empty;
+
+__attribute__ ((__noinline__)) void
+aarchpcs_overflow (int, int, int, int, int, int, int, int, Empty);
+
+/*
+**aarchpcs_overflow_call:
+** ...
+** mov w7, 7
+** mov w6, 6
+** mov w5, 5
+** mov w4, 4
+** mov w3, 3
+** mov w2, 2
+** mov w1, 1
+** mov w0, 0
+** bl aarchpcs_overflow
+** ...
+*/
+
+void
+aarchpcs_overflow_call (void)
+{
+ Empty e;
+ aarchpcs_overflow (0, 1, 2, 3, 4, 5, 6, 7, e);
+}
+
+__attribute__ ((__noinline__, preserve_none)) void
+preserve_none_overflow (int, int, int, int, int, int, int, int, int, int, int,
int, int, int, int, int, int, int, int, int, int, int, int, int, Empty);
+
+/*
+**preserve_none_overflow_call:
+** ...
+** mov w15, 23
+** mov w9, 22
+** mov w14, 21
+** mov w13, 20
+** mov w12, 19
+** mov w11, 18
+** mov w10, 17
+** mov w7, 16
+** mov w6, 15
+** mov w5, 14
+** mov w4, 13
+** mov w3, 12
+** mov w2, 11
+** mov w1, 10
+** mov w0, 9
+** mov w28, 8
+** mov w27, 7
+** mov w26, 6
+** mov w25, 5
+** mov w24, 4
+** mov w23, 3
+** mov w22, 2
+** mov w21, 1
+** mov w20, 0
+** ...
+** bl preserve_none_overflow
+** ...
+*/
+
+__attribute__ ((preserve_none)) void
+preserve_none_overflow_call (void)
+{
+ Empty e;
+ preserve_none_overflow(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, e);
+}
+
--
2.34.1