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.
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))
--- /dev/null
+/* { 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 } } */