https://gcc.gnu.org/g:d56eb2fbcb5a65ca738534fab640e36b9061b0b2

commit r16-5427-gd56eb2fbcb5a65ca738534fab640e36b9061b0b2
Author: Alfie Richards <[email protected]>
Date:   Wed Nov 19 11:47:09 2025 +0000

    aarch64: Fix ICE when laying out arguments of size 0 [PR 122763]
    
    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.

Diff:
---
 gcc/config/aarch64/aarch64.cc               | 15 +++---
 gcc/testsuite/gcc.target/aarch64/pr122763.c | 75 +++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 9 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 60608a19078d..6dfdaa4fb9b0 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -7656,11 +7656,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
@@ -7863,10 +7863,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 000000000000..bd90c665236b
--- /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);
+}
+

Reply via email to