https://gcc.gnu.org/g:4a2a0a4360fa37a30b8c00a29095ad9fdb63c2f3

commit r17-4454-g4a2a0a4360fa37a30b8c00a29095ad9fdb63c2f3
Author: Michiel Derhaeg <[email protected]>
Date:   Fri Sep 18 17:15:50 2026 -0600

    [PATCH] RISC-V: Avoid emitting shNadd with a virtual register base
    
    From: Loeka Rogge <[email protected]>
    
    A shNadd whose base is a virtual register prevents the frame offset from
    being folded in later, leaving a long sequence behind.
    
    gcc.target/riscv/zba-shNadd-11.c, compiled with -march=rv64i_zba
    -mabi=lp64 -O2, produced:
    
            li      a5,514
            sh3add  t0,a5,sp
            li      a0,-513
            sh3add  a0,a0,t0
    
    and now produces:
    
            addi    a0,sp,8
    
    Regtested on rv32gc and rv64gc.
    
    gcc/ChangeLog:
    
            * config/riscv/riscv.cc (synthesize_add): Do not form shNadd
            when the base register is a virtual register.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/riscv/zba-shNadd-11.c: New test.
    
    Signed-off-by: Michiel Derhaeg <[email protected]>
    Signed-off-by: Loeka Rogge <[email protected]>

Diff:
---
 gcc/config/riscv/riscv.cc                      |  6 +++++-
 gcc/testsuite/gcc.target/riscv/zba-shNadd-11.c | 22 ++++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 49e7476b8322..f20f2a6bd3e1 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -16635,9 +16635,13 @@ synthesize_add (rtx operands[3])
     }
 
   /* If we can shift the constant by 1, 2, or 3 bit positions
-     and the result is a cheaper constant, then do so.  */
+     and the result is a cheaper constant, then do so.
+     Virtual registers are later eliminated to FP/SP + a constant.
+     Putting them inside a shNadd prevents that folding.  */
   ival = INTVAL (operands[2]);
   if (TARGET_ZBA
+      && !(REG_P (operands[1])
+          && VIRTUAL_REGISTER_P (operands[1]))
       && (((ival % 2) == 0 && budget1
           > riscv_integer_cost (ival >> 1, true))
           || ((ival % 4) == 0 && budget1
diff --git a/gcc/testsuite/gcc.target/riscv/zba-shNadd-11.c 
b/gcc/testsuite/gcc.target/riscv/zba-shNadd-11.c
new file mode 100644
index 000000000000..1e920ef685b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/zba-shNadd-11.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32i_zba -mabi=ilp32 -O2" { target rv32 } } */
+/* { dg-options "-march=rv64i_zba -mabi=lp64 -O2" { target rv64 } } */
+/* { dg-skip-if "" { *-*-* } { "-flto" } } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+void bar (void *);
+
+/*
+** foo:
+**     ...
+**     addi    a0,sp,8
+**     call    bar
+**     ...
+*/
+
+void
+foo ()
+{
+  char baz[4104];
+  bar (baz);
+}

Reply via email to