aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>2024-02-01 23:45:50 +0800
committerLehua Ding <lehua.ding@rivai.ai>2024-02-02 16:56:55 +0800
commit74489c19070703361acc20bc172f304cae845a96 (patch)
treef81584364efb863b87cc2c5b64585dedfae1897a
parent8939854ad67fbc6c650370ab28d344bbe51f9bfd (diff)
downloadgcc-74489c19070703361acc20bc172f304cae845a96.zip
gcc-74489c19070703361acc20bc172f304cae845a96.tar.gz
gcc-74489c19070703361acc20bc172f304cae845a96.tar.bz2
RISC-V: Allow LICM hoist POLY_INT configuration code sequence
Realize in recent benchmark evaluation (coremark-pro zip-test): vid.v v2 vmv.v.i v5,0 .L9: vle16.v v3,0(a4) vrsub.vx v4,v2,a6 ---> LICM failed to hoist it outside the loop. The root cause is: (insn 56 47 57 4 (set (subreg:DI (reg:HI 220) 0) (reg:DI 223)) "rvv.c":11:9 208 {*movdi_64bit} -> Its result used by the following vrsub.vx then supress the hoist of the vrsub.vx (nil)) (insn 57 56 59 4 (set (reg:RVVMF2HI 216) (if_then_else:RVVMF2HI (unspec:RVVMF32BI [ (const_vector:RVVMF32BI repeat [ (const_int 1 [0x1]) ]) (reg:DI 350) (const_int 2 [0x2]) repeated x2 (const_int 1 [0x1]) (reg:SI 66 vl) (reg:SI 67 vtype) ] UNSPEC_VPREDICATE) (minus:RVVMF2HI (vec_duplicate:RVVMF2HI (reg:HI 220)) (reg:RVVMF2HI 217)) (unspec:RVVMF2HI [ (reg:DI 0 zero) ] UNSPEC_VUNDEF))) "rvv.c":11:9 6938 {pred_subrvvmf2hi_reverse_scalar} (expr_list:REG_DEAD (reg:HI 220) (nil))) This patch fixes it generate (set (reg:HI) (subreg:HI (reg:DI))) instead of (set (subreg:DI (reg:DI)) (reg:DI)). After this patch: vid.v v2 vrsub.vx v2,v2,a7 vmv.v.i v4,0 .L3: vle16.v v3,0(a4) Tested on both RV32 and RV64 no regression. gcc/ChangeLog: * config/riscv/riscv.cc (riscv_legitimize_move): Fix poly_int dest generation. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/autovec/poly_licm-1.c: New test. * gcc.target/riscv/rvv/autovec/poly_licm-2.c: New test.
-rw-r--r--gcc/config/riscv/riscv.cc9
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/poly_licm-1.c18
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/autovec/poly_licm-2.c27
3 files changed, 50 insertions, 4 deletions
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index d7cdd71..3230fe1 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2728,16 +2728,17 @@ riscv_legitimize_move (machine_mode mode, rtx dest, rtx src)
(const_poly_int:HI [m, n])
(const_poly_int:SI [m, n]). */
rtx tmp = gen_reg_rtx (Pmode);
- riscv_legitimize_poly_move (Pmode, gen_lowpart (Pmode, dest), tmp,
- src);
+ rtx tmp2 = gen_reg_rtx (Pmode);
+ riscv_legitimize_poly_move (Pmode, tmp2, tmp, src);
+ emit_move_insn (dest, gen_lowpart (mode, tmp2));
}
else
{
/* In RV32 system, handle (const_poly_int:SI [m, n])
(const_poly_int:DI [m, n]).
In RV64 system, handle (const_poly_int:DI [m, n]).
- FIXME: Maybe we could gen SImode in RV32 and then sign-extend to DImode,
- the offset should not exceed 4GiB in general. */
+ FIXME: Maybe we could gen SImode in RV32 and then sign-extend to
+ DImode, the offset should not exceed 4GiB in general. */
rtx tmp = gen_reg_rtx (mode);
riscv_legitimize_poly_move (mode, dest, tmp, src);
}
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/poly_licm-1.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/poly_licm-1.c
new file mode 100644
index 0000000..b7da65f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/poly_licm-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+
+extern int wsize;
+
+typedef unsigned short Posf;
+#define NIL 0
+
+void foo (Posf *p)
+{
+ register unsigned n, m;
+ do {
+ m = *--p;
+ *p = (Posf)(m >= wsize ? m-wsize : NIL);
+ } while (--n);
+}
+
+/* { dg-final { scan-assembler-times {vid\.v\s+v[0-9]+\s+addi\s+\s*[a-x0-9]+,\s*[a-x0-9]+,\s*-1\s+vrsub\.vx\s+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/poly_licm-2.c b/gcc/testsuite/gcc.target/riscv/rvv/autovec/poly_licm-2.c
new file mode 100644
index 0000000..ffb3c63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/poly_licm-2.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O3 -fno-schedule-insns -fno-schedule-insns2" } */
+
+typedef unsigned short uint16_t;
+
+void AAA (uint16_t *x, uint16_t *y, unsigned wsize, unsigned count)
+{
+ unsigned m = 0, n = count;
+ register uint16_t *p;
+
+ p = x;
+
+ do {
+ m = *--p;
+ *p = (uint16_t)(m >= wsize ? m-wsize : 0);
+ } while (--n);
+
+ n = wsize;
+ p = y;
+
+ do {
+ m = *--p;
+ *p = (uint16_t)(m >= wsize ? m-wsize : 0);
+ } while (--n);
+}
+
+/* { dg-final { scan-assembler-times {vid\.v\s+v[0-9]+\s+vrsub\.vx\s+} 2 } } */