aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBohan Lei <garthlei@linux.alibaba.com>2024-09-12 10:28:03 +0800
committerPan Li <pan2.li@intel.com>2024-09-12 14:15:17 +0800
commit3f212eabbba3edc1827d6da53cf6d5a64c6524f0 (patch)
tree1673314c9b844b9b5106c14f9beecb56f6596c26
parent5958279509c4601499ac22629512f1723e6744b4 (diff)
downloadgcc-3f212eabbba3edc1827d6da53cf6d5a64c6524f0.zip
gcc-3f212eabbba3edc1827d6da53cf6d5a64c6524f0.tar.gz
gcc-3f212eabbba3edc1827d6da53cf6d5a64c6524f0.tar.bz2
RISC-V: Eliminate latter vsetvl when fused
Hi all, A simple assembly check has been added in this version. Previous version: https://gcc.gnu.org/pipermail/gcc-patches/2024-September/662783.html Thanks, Bohan ------ The current vsetvl pass eliminates a vsetvl instruction when the previous info is "available," but does not when "compatible." This can lead to not only redundancy, but also incorrect behaviors when the previous info happens to be compatible with a later vector instruction, which ends of using the vsetvl info that should have been eliminated, as is shown in the testcase. This patch eliminates the vsetvl when the previous info is "compatible." gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc (pre_vsetvl::fuse_local_vsetvl_info): Delete vsetvl insn when `prev_info` is compatible gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/vsetvl/vsetvl_bug-4.c: New test.
-rw-r--r--gcc/config/riscv/riscv-vsetvl.cc3
-rw-r--r--gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_bug-4.c19
2 files changed, 22 insertions, 0 deletions
diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index ce83168..030ffbe 100644
--- a/gcc/config/riscv/riscv-vsetvl.cc
+++ b/gcc/config/riscv/riscv-vsetvl.cc
@@ -2796,6 +2796,9 @@ pre_vsetvl::fuse_local_vsetvl_info ()
curr_info.dump (dump_file, " ");
}
m_dem.merge (prev_info, curr_info);
+ if (!curr_info.vl_used_by_non_rvv_insn_p ()
+ && vsetvl_insn_p (curr_info.get_insn ()->rtl ()))
+ m_delete_list.safe_push (curr_info);
if (curr_info.get_read_vl_insn ())
prev_info.set_read_vl_insn (curr_info.get_read_vl_insn ());
if (dump_file && (dump_flags & TDF_DETAILS))
diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_bug-4.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_bug-4.c
new file mode 100644
index 0000000..04a8ff2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/vsetvl_bug-4.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gcv -mabi=lp64d -O2 -fno-schedule-insns -fdump-rtl-vsetvl-details" } */
+
+#include <riscv_vector.h>
+
+vuint16m1_t
+foo (vuint16m1_t a, vuint16m1_t b, size_t avl)
+{
+ size_t vl;
+ vuint16m1_t ret;
+ uint16_t c = __riscv_vmv_x_s_u16m1_u16(a);
+ vl = __riscv_vsetvl_e8mf2 (avl);
+ ret = __riscv_vadd_vx_u16m1 (a, c, avl);
+ ret = __riscv_vadd_vv_u16m1 (ret, a, vl);
+ return ret;
+}
+
+/* { dg-final { scan-rtl-dump "Eliminate insn" "vsetvl" } } */
+/* { dg-final { scan-assembler-times {vsetvli} 2 } } */