The early-clobber scratch in *<any_extract>3 is unnecessary: slli
reads its source before writing, so the destination register can
safely hold the intermediate value. This reduces register pressure
and makes the split output simpler.
gcc/ChangeLog:
* config/riscv/riscv.md (*<any_extract:optab><GPR:mode>3):
Remove (clobber (match_scratch)) and use operand 0 as the
intermediate destination for the shift-left half of the split.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/extract-zero-no-scratch.c: New test.
* gcc.target/riscv/extract-sign-no-scratch.c: New test.
---
gcc/config/riscv/riscv.md | 7 +++----
.../gcc.target/riscv/extract-sign-no-scratch.c | 18 ++++++++++++++++++
.../gcc.target/riscv/extract-zero-no-scratch.c | 18 ++++++++++++++++++
3 files changed, 39 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/gcc.target/riscv/extract-sign-no-scratch.c
create mode 100644 gcc/testsuite/gcc.target/riscv/extract-zero-no-scratch.c
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 2cd26fa99ab..f10a08460ac 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3157,8 +3157,7 @@ (define_insn_and_split "*<any_extract:optab><GPR:mode>3"
(any_extract:GPR
(match_operand:GPR 1 "register_operand" " r")
(match_operand 2 "const_int_operand")
- (match_operand 3 "const_int_operand")))
- (clobber (match_scratch:GPR 4 "=&r"))]
+ (match_operand 3 "const_int_operand")))]
"!((TARGET_ZBS || TARGET_XTHEADBS || TARGET_ZICOND
|| TARGET_XVENTANACONDOPS || TARGET_SFB_ALU)
&& (INTVAL (operands[2]) == 1))
@@ -3169,10 +3168,10 @@ (define_insn_and_split "*<any_extract:optab><GPR:mode>3"
&& (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
"#"
"&& reload_completed"
- [(set (match_dup 4)
+ [(set (match_dup 0)
(ashift:GPR (match_dup 1) (match_dup 2)))
(set (match_dup 0)
- (<extract_shift>:GPR (match_dup 4) (match_dup 3)))]
+ (<extract_shift>:GPR (match_dup 0) (match_dup 3)))]
{
int regbits = GET_MODE_BITSIZE (GET_MODE (operands[0])).to_constant ();
int sizebits = INTVAL (operands[2]);
diff --git a/gcc/testsuite/gcc.target/riscv/extract-sign-no-scratch.c
b/gcc/testsuite/gcc.target/riscv/extract-sign-no-scratch.c
new file mode 100644
index 00000000000..e908737fb5b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/extract-sign-no-scratch.c
@@ -0,0 +1,18 @@
+/* Verify *sign_extract splitter uses the same dest for slli and srai. */
+/* { dg-do compile { target { ! riscv_abi_e } } } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O2" } */
+/* { dg-skip-if "" { *-*-* } { "-Os" "-Oz" "-Og" "-flto" } } */
+
+long sign_ext_11_5 (long x) { return ((x << 48) >> 53); }
+long sign_ext_16_8 (long x) { return ((x << 40) >> 48); }
+long sign_ext_10_20 (long x) { return ((x << 34) >> 54); }
+
+/* { dg-final { scan-assembler-times "slli\t" 3 } } */
+/* { dg-final { scan-assembler-times "srai\t" 3 } } */
+/* { dg-final { scan-assembler "slli\ta0,a0,48" } } */
+/* { dg-final { scan-assembler "srai\ta0,a0,53" } } */
+/* { dg-final { scan-assembler "slli\ta0,a0,40" } } */
+/* { dg-final { scan-assembler "srai\ta0,a0,48" } } */
+/* { dg-final { scan-assembler "slli\ta0,a0,34" } } */
+/* { dg-final { scan-assembler "srai\ta0,a0,54" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/extract-zero-no-scratch.c
b/gcc/testsuite/gcc.target/riscv/extract-zero-no-scratch.c
new file mode 100644
index 00000000000..6d6fdecf3a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/extract-zero-no-scratch.c
@@ -0,0 +1,18 @@
+/* Verify *zero_extract splitter uses the same dest for slli and srli. */
+/* { dg-do compile { target { ! riscv_abi_e } } } */
+/* { dg-require-effective-target rv64 } */
+/* { dg-options "-march=rv64gc -mabi=lp64d -O2" } */
+/* { dg-skip-if "" { *-*-* } { "-Os" "-Oz" "-Og" "-flto" } } */
+
+unsigned long zero_ext_20_8 (unsigned long x) { return (x >> 8) & 0xfffffUL;
}
+unsigned long zero_ext_16_8 (unsigned long x) { return (x >> 8) & 0xffffUL;
}
+unsigned long zero_ext_13_20 (unsigned long x) { return (x >> 20) & 0x1fffUL;
}
+
+/* { dg-final { scan-assembler-times "slli\t" 3 } } */
+/* { dg-final { scan-assembler-times "srli\t" 3 } } */
+/* { dg-final { scan-assembler "slli\ta0,a0,36" } } */
+/* { dg-final { scan-assembler "srli\ta0,a0,44" } } */
+/* { dg-final { scan-assembler "slli\ta0,a0,40" } } */
+/* { dg-final { scan-assembler "srli\ta0,a0,48" } } */
+/* { dg-final { scan-assembler "slli\ta0,a0,31" } } */
+/* { dg-final { scan-assembler "srli\ta0,a0,51" } } */
--
2.52.0