aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorJuzhe-Zhong <juzhe.zhong@rivai.ai>2023-05-09 10:19:34 +0800
committerKito Cheng <kito.cheng@sifive.com>2023-05-10 16:21:44 +0800
commit69f3914414a303f0e2c8246e08925f90c207846c (patch)
tree2c04d16b131663ca229f9f694fdb7b53b6b8f709 /gcc/config
parent3ef0ebf901f6299e76237777e1b72b65c795fac0 (diff)
downloadgcc-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.
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/riscv/riscv-vsetvl.cc25
1 files changed, 25 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;