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]>
---
gcc/config/riscv/riscv.cc | 6 ++++-
.../gcc.target/riscv/zba-shNadd-11.c | 22 +++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/zba-shNadd-11.c
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index f8b54fc4ae6..0b73f03e169 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -16579,9 +16579,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 00000000000..1e920ef685b
--- /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);
+}
--
2.54.0