aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLehua Ding <lehua.ding@rivai.ai>2023-11-08 21:17:48 +0800
committerLehua Ding <lehua.ding@rivai.ai>2023-11-08 21:33:19 +0800
commit8cf7b936d44c37558b518cbbea4b21ed502b651e (patch)
treee7f03aef162bf377ec628a93ec55e5a8344d1379
parentfdd912690344fdfa6ef93d1e8923dae1bed3c965 (diff)
downloadgcc-8cf7b936d44c37558b518cbbea4b21ed502b651e.zip
gcc-8cf7b936d44c37558b518cbbea4b21ed502b651e.tar.gz
gcc-8cf7b936d44c37558b518cbbea4b21ed502b651e.tar.bz2
RISC-V: Removed unnecessary sign-extend for vsetvl
Hi, This patch try to combine bellow two insns and then further remove unnecessary sign_extend operations. This optimization is borrowed from LLVM (https://godbolt.org/z/4f6v56xej): (set (reg:DI 134 [ _1 ]) (unspec:DI [ (const_int 19 [0x13]) (const_int 8 [0x8]) (const_int 5 [0x5]) (const_int 2 [0x2]) repeated x2 ] UNSPEC_VSETVL)) (set (reg/v:DI 135 [ <retval> ]) (sign_extend:DI (subreg:SI (reg:DI 134 [ _1 ]) 0))) The reason we can remove signe_extend is because currently the vl value returned by the vsetvl instruction ranges from 0 to 65536 (uint16_t), and bits 17 to 63 (including 31) are always 0, so there is no change after sign_extend. Note that for HI and QI modes we cannot do this. Of course, if the range returned by vsetvl later expands to 32 bits, then this combine pattern needs to be removed. But that could be a long time from now. gcc/ChangeLog: * config/riscv/vector.md (*vsetvldi_no_side_effects_si_extend): New combine pattern. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/vsetvl/vsetvl_int.c: New test.
-rw-r--r--gcc/config/riscv/vector.md41
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_int.c31
2 files changed, 72 insertions, 0 deletions
diff --git a/gcc/config/riscv/vector.md b/gcc/config/riscv/vector.md
index e23f649..d1499d3 100644
--- a/gcc/config/riscv/vector.md
+++ b/gcc/config/riscv/vector.md
@@ -1604,6 +1604,47 @@
[(set_attr "type" "vsetvl")
(set_attr "mode" "SI")])
+;; This pattern use to combine bellow two insns and then further remove
+;; unnecessary sign_extend operations:
+;; (set (reg:DI 134 [ _1 ])
+;; (unspec:DI [
+;; (const_int 19 [0x13])
+;; (const_int 8 [0x8])
+;; (const_int 5 [0x5])
+;; (const_int 2 [0x2]) repeated x2
+;; ] UNSPEC_VSETVL))
+;; (set (reg/v:DI 135 [ <retval> ])
+;; (sign_extend:DI (subreg:SI (reg:DI 134 [ _1 ]) 0)))
+;;
+;; The reason we can remove signe_extend is because currently the vl value
+;; returned by the vsetvl instruction ranges from 0 to 65536 (uint16_t), and
+;; bits 17 to 63 (including 31) are always 0, so there is no change after
+;; sign_extend. Note that for HI and QI modes we cannot do this.
+;; Of course, if the range of instructions returned by vsetvl later expands
+;; to 32bits, then this combine pattern needs to be removed. But that could be
+;; a long time from now.
+(define_insn_and_split "*vsetvldi_no_side_effects_si_extend"
+ [(set (match_operand:DI 0 "register_operand")
+ (sign_extend:DI
+ (subreg:SI
+ (unspec:DI [(match_operand:P 1 "csr_operand")
+ (match_operand 2 "const_int_operand")
+ (match_operand 3 "const_int_operand")
+ (match_operand 4 "const_int_operand")
+ (match_operand 5 "const_int_operand")] UNSPEC_VSETVL) 0)))]
+ "TARGET_VECTOR && TARGET_64BIT"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (unspec:DI [(match_dup 1)
+ (match_dup 2)
+ (match_dup 3)
+ (match_dup 4)
+ (match_dup 5)] UNSPEC_VSETVL))]
+ ""
+ [(set_attr "type" "vsetvl")
+ (set_attr "mode" "SI")])
+
;; RVV machine description matching format
;; (define_insn ""
;; [(set (match_operand:MODE 0)
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_int.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_int.c
new file mode 100644
index 0000000..4cdd587
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_int.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d" } */
+
+#include "riscv_vector.h"
+
+void bar1 (int32_t a);
+
+int32_t
+foo1 ()
+{
+ int32_t a = __riscv_vsetvl_e8mf8(19);
+ bar1 (a);
+ return a;
+}
+
+void bar2 (uint32_t a);
+
+uint32_t
+foo2 ()
+{
+ uint32_t a = __riscv_vsetvl_e8mf8(19);
+ bar2 (a);
+ return a;
+}
+
+int32_t foo3 ()
+{
+ return __riscv_vsetvl_e8mf8(19);
+}
+
+/* { dg-final { scan-assembler-not {sext\.w} { target { no-opts "-O0" "-g" } } } } */