diff options
author | Juzhe-Zhong <juzhe.zhong@rivai.ai> | 2023-05-09 10:19:34 +0800 |
---|---|---|
committer | Kito Cheng <kito.cheng@sifive.com> | 2023-05-10 16:21:44 +0800 |
commit | 69f3914414a303f0e2c8246e08925f90c207846c (patch) | |
tree | 2c04d16b131663ca229f9f694fdb7b53b6b8f709 | |
parent | 3ef0ebf901f6299e76237777e1b72b65c795fac0 (diff) | |
download | gcc-69f3914414a303f0e2c8246e08925f90c207846c.zip gcc-69f3914414a303f0e2c8246e08925f90c207846c.tar.gz gcc-69f3914414a303f0e2c8246e08925f90c207846c.tar.bz2 |
RISC-V: Fix dead loop for user vsetvli intrinsic avl checking [PR109773]
This patch is fix dead loop in vsetvl intrinsic avl checking.
vsetvli->get_def () has vsetvli->get_def () has vsetvli.....
Then it will keep looping in the vsetvli avl checking which is a dead loop.
PR target/109773
gcc/ChangeLog:
* config/riscv/riscv-vsetvl.cc (avl_source_has_vsetvl_p): New function.
(source_equal_p): Fix dead loop in vsetvl avl checking.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/rvv/vsetvl/pr109773-1.c: New test.
* gcc.target/riscv/rvv/vsetvl/pr109773-2.c: New test.
-rw-r--r-- | gcc/config/riscv/riscv-vsetvl.cc | 25 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr109773-1.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr109773-2.c | 26 |
3 files changed, 71 insertions, 0 deletions
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index d4d6f33..a69a418 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -1057,6 +1057,24 @@ change_vsetvl_insn (const insn_info *insn, const vector_insn_info &info) } static bool +avl_source_has_vsetvl_p (set_info *avl_source) +{ + if (!avl_source) + return false; + if (!avl_source->insn ()) + return false; + if (avl_source->insn ()->is_real ()) + return vsetvl_insn_p (avl_source->insn ()->rtl ()); + hash_set<set_info *> sets = get_all_sets (avl_source, true, false, true); + for (const auto set : sets) + { + if (set->insn ()->is_real () && vsetvl_insn_p (set->insn ()->rtl ())) + return true; + } + return false; +} + +static bool source_equal_p (insn_info *insn1, insn_info *insn2) { if (!insn1 || !insn2) @@ -1098,6 +1116,13 @@ source_equal_p (insn_info *insn1, insn_info *insn2) vector_insn_info insn1_info, insn2_info; insn1_info.parse_insn (insn1); insn2_info.parse_insn (insn2); + + /* To avoid dead loop, we don't optimize a vsetvli def has vsetvli + instructions which will complicate the situation. */ + if (avl_source_has_vsetvl_p (insn1_info.get_avl_source ()) + || avl_source_has_vsetvl_p (insn2_info.get_avl_source ())) + return false; + if (insn1_info.same_vlmax_p (insn2_info) && insn1_info.compatible_avl_p (insn2_info)) return true; diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr109773-1.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr109773-1.c new file mode 100644 index 0000000..8656e47 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr109773-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -fno-schedule-insns -fno-schedule-insns2" } */ + +#include "riscv_vector.h" + +void f (int32_t *a, int32_t *b, int n) +{ + if (n <= 0) + return; + int i = n; + size_t vl = __riscv_vsetvl_e8mf4 (i); + for (; i >= 0; i--) + { + vint32m1_t v = __riscv_vle32_v_i32m1 (a + i, vl); + __riscv_vse32_v_i32m1 (b + i, v, vl); + vl = __riscv_vsetvl_e8mf4 (vl); + } +} + +/* { dg-final { scan-assembler-times {vsetvli} 3 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-Oz" no-opts "-g" no-opts "-funroll-loops" } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr109773-2.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr109773-2.c new file mode 100644 index 0000000..7bfbaaf --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/pr109773-2.c @@ -0,0 +1,26 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gcv -mabi=ilp32 -fno-tree-vectorize -fno-schedule-insns -fno-schedule-insns2" } */ + +#include "riscv_vector.h" + +void f (int32_t * a, int32_t * b, int n) +{ + if (n <= 0) + return; + int i = n; + size_t vl = __riscv_vsetvl_e8mf4 (i); + for (; i >= 0; i--) + { + vint32m1_t v = __riscv_vle32_v_i32m1 (a + i, vl); + v = __riscv_vle32_v_i32m1_tu (v, a + i + 100, vl); + __riscv_vse32_v_i32m1 (b + i, v, vl); + + if (i >= vl) + continue; + if (i == 0) + return; + vl = __riscv_vsetvl_e8mf4 (vl); + } +} + +/* { dg-final { scan-assembler {vsetvli} { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-Oz" no-opts "-g" no-opts "-funroll-loops" } } } } */ |