https://gcc.gnu.org/g:3f212eabbba3edc1827d6da53cf6d5a64c6524f0

commit r15-3595-g3f212eabbba3edc1827d6da53cf6d5a64c6524f0
Author: Bohan Lei <garth...@linux.alibaba.com>
Date:   Thu Sep 12 10:28:03 2024 +0800

    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.

Diff:
---
 gcc/config/riscv/riscv-vsetvl.cc                      |  3 +++
 .../gcc.target/riscv/rvv/vsetvl/vsetvl_bug-4.c        | 19 +++++++++++++++++++
 2 files changed, 22 insertions(+)

diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc
index ce831685439a..030ffbe2ebbc 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 000000000000..04a8ff2945a3
--- /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 } } */

Reply via email to