Changes since v2:
- Broke out the hunk corresponding to alloca in epilogue expansion in
a seperate patch.
---
If the constant used for stack offset can be expressed as sum of two S12
values, the constant need not be materialized (in a reg) and instead the
two S12 bits can be added to instructions involved with frame pointer.
This avoids burning a register and more importantly can often get down
to be 2 insn vs. 3.
The prev patches to generally avoid LUI based const materialization didn't
fix this PR and need this directed fix in funcion prologue/epilogue
expansion.
This fix doesn't move the neddle for SPEC, at all, but it is still a
win considering gcc generates one insn fewer than llvm for the test ;-)
gcc-13.1 release | gcc 230823 | |
|g6619b3d4c15c| This patch | clang/llvm
-
li t0,-4096 | lit0,-4096 | addi sp,sp,-2048 | addi
sp,sp,-2048
addit0,t0,2016 | addi t0,t0,2032| add sp,sp,-16 | addi sp,sp,-32
li a4,4096 | add sp,sp,t0 | add a5,sp,a0| add a1,sp,16
add sp,sp,t0 | addi a5,sp,-2032 | sbzero,0(a5) | add a0,a0,a1
li a5,-4096 | add a0,a5,a0 | addi sp,sp,2032 | sb zero,0(a0)
addia4,a4,-2032 | lit0, 4096 | addi sp,sp,32| addi sp,sp,2032
add a4,a4,a5 | sbzero,2032(a0) | ret | addi sp,sp,48
addia5,sp,16 | addi t0,t0,-2032 | | ret
add a5,a4,a5 | add sp,sp,t0 |
add a0,a5,a0 | ret |
li t0,4096 |
sd a5,8(sp) |
sb zero,2032(a0)|
addit0,t0,-2016 |
add sp,sp,t0 |
ret |
gcc/ChangeLog:
PR target/105733
* config/riscv/riscv.h: New macros for with aligned offsets.
* config/riscv/riscv.cc (riscv_split_sum_of_two_s12): New
function to split a sum of two s12 values into constituents.
(riscv_expand_prologue): Handle offset being sum of two S12.
(riscv_expand_epilogue): Ditto.
* config/riscv/riscv-protos.h (riscv_split_sum_of_two_s12): New.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/pr105733.c: New Test.
* gcc.target/riscv/rvv/autovec/vls/spill-1.c: Adjust to not
expect LUI 4096.
* gcc.target/riscv/rvv/autovec/vls/spill-2.c: Ditto.
* gcc.target/riscv/rvv/autovec/vls/spill-3.c: Ditto.
* gcc.target/riscv/rvv/autovec/vls/spill-4.c: Ditto.
* gcc.target/riscv/rvv/autovec/vls/spill-5.c: Ditto.
* gcc.target/riscv/rvv/autovec/vls/spill-6.c: Ditto.
* gcc.target/riscv/rvv/autovec/vls/spill-7.c: Ditto.
Signed-off-by: Vineet Gupta
---
gcc/config/riscv/riscv-protos.h | 2 +
gcc/config/riscv/riscv.cc | 54 +--
gcc/config/riscv/riscv.h | 7 +++
gcc/testsuite/gcc.target/riscv/pr105733.c | 15 ++
.../riscv/rvv/autovec/vls/spill-1.c | 4 +-
.../riscv/rvv/autovec/vls/spill-2.c | 4 +-
.../riscv/rvv/autovec/vls/spill-3.c | 4 +-
.../riscv/rvv/autovec/vls/spill-4.c | 4 +-
.../riscv/rvv/autovec/vls/spill-5.c | 4 +-
.../riscv/rvv/autovec/vls/spill-6.c | 4 +-
.../riscv/rvv/autovec/vls/spill-7.c | 4 +-
11 files changed, 89 insertions(+), 17 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/pr105733.c
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index c64aae18deb9..0704968561bb 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -167,6 +167,8 @@ extern void riscv_subword_address (rtx, rtx *, rtx *, rtx
*, rtx *);
extern void riscv_lshift_subword (machine_mode, rtx, rtx, rtx *);
extern enum memmodel riscv_union_memmodels (enum memmodel, enum memmodel);
extern bool riscv_reg_frame_related (rtx);
+extern void riscv_split_sum_of_two_s12 (HOST_WIDE_INT, HOST_WIDE_INT *,
+ HOST_WIDE_INT *);
/* Routines implemented in riscv-c.cc. */
void riscv_cpu_cpp_builtins (cpp_reader *);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index d0c22058b8c3..2ecbcf1d0af8 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -4075,6 +4075,32 @@ riscv_split_doubleword_move (rtx dest, rtx src)
riscv_emit_move (riscv_subword (dest, true), riscv_subword (src, true));
}
}
+
+/* Constant VAL is known to be sum of two S12 constants. Break it into
+ comprising BASE and OFF.
+ Numerically S12 is -2048 to 2047, however it uses the more conservative
+ range -2048 to 2032 as offsets pertain to stack related registers. */
+
+void
+riscv_split_sum_of_two_s12 (HOST_WIDE_INT val, HOST_WIDE_INT *base,
+ HOST_WIDE_INT *off)
+{
+ if (SUM_OF_TWO_S12_N (val))
+{
+