From: Juzhe-Zhong <juzhe.zh...@rivai.ai> void f (int8_t* base1,int8_t* base2,int8_t* out,int n) { vint8mf4_t v = __riscv_vle8_v_i8mf4 (base1, 32); for (int i = 0; i < n; i++){ v = __riscv_vor_vx_i8mf4 (v, 101, 32); v = __riscv_vle8_v_i8mf4_tu (v, base2, 32); } __riscv_vse8_v_i8mf4 (out, v, 32); }
before this patch: f: li a5,32 vsetvli zero,a5,e8,mf4,tu,ma vle8.v v1,0(a0) ble a3,zero,.L2 li t0,0 li a0,101 .L3: addiw t0,t0,1 vor.vx v1,v1,a0 vle8.v v1,0(a1) bne a3,t0,.L3 .L2: vsetvli zero,zero,e8,mf4,tu,ma vse8.v v1,0(a2) ret afther this patch: f: li a5,32 vsetvli zero,a5,e8,mf4,tu,ma vle8.v v1,0(a0) ble a3,zero,.L2 li t0,0 li a0,101 .L3: addiw t0,t0,1 vor.vx v1,v1,a0 vle8.v v1,0(a1) bne a3,t0,.L3 .L2: vse8.v v1,0(a2) ret gcc/ChangeLog: * config/riscv/riscv-vsetvl.cc (vector_infos_manager::all_avail_in_compatible_p): New function. (pass_vsetvl::refine_vsetvls): Remove redundant vsetvli. * config/riscv/riscv-vsetvl.h: New function declare. gcc/testsuite/ChangeLog: * gcc.target/riscv/rvv/vsetvl/avl_single-102.c: New test. --- gcc/config/riscv/riscv-vsetvl.cc | 67 ++++++++++++++++++- gcc/config/riscv/riscv-vsetvl.h | 1 + .../riscv/rvv/vsetvl/avl_single-102.c | 16 +++++ 3 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-102.c diff --git a/gcc/config/riscv/riscv-vsetvl.cc b/gcc/config/riscv/riscv-vsetvl.cc index 4948e5d4c5e..58568b45010 100644 --- a/gcc/config/riscv/riscv-vsetvl.cc +++ b/gcc/config/riscv/riscv-vsetvl.cc @@ -2376,6 +2376,23 @@ vector_infos_manager::all_empty_predecessor_p (const basic_block cfg_bb) const return true; } +bool +vector_infos_manager::all_avail_in_compatible_p (const basic_block cfg_bb) const +{ + const auto &info = vector_block_infos[cfg_bb->index].local_dem; + sbitmap avin = vector_avin[cfg_bb->index]; + unsigned int bb_index; + sbitmap_iterator sbi; + EXECUTE_IF_SET_IN_BITMAP (avin, 0, bb_index, sbi) + { + const auto &avin_info + = static_cast<const vl_vtype_info &> (*vector_exprs[bb_index]); + if (!info.compatible_p (avin_info)) + return false; + } + return true; +} + bool vector_infos_manager::all_same_avl_p (const basic_block cfg_bb, sbitmap bitdata) const @@ -3741,9 +3758,53 @@ pass_vsetvl::refine_vsetvls (void) const m_vector_manager->to_refine_vsetvls.add (rinsn); continue; } - rinsn = PREV_INSN (rinsn); - rtx new_pat = gen_vsetvl_pat (VSETVL_VTYPE_CHANGE_ONLY, info, NULL_RTX); - change_insn (rinsn, new_pat); + + /* Optimize such case: + void f (int8_t* base1,int8_t* base2,int8_t* out,int n) + { + vint8mf4_t v = __riscv_vle8_v_i8mf4 (base1, 32); + for (int i = 0; i < n; i++){ + v = __riscv_vor_vx_i8mf4 (v, 101, 32); + v = __riscv_vle8_v_i8mf4_tu (v, base2, 32); + } + __riscv_vse8_v_i8mf4 (out, v, 32); + } + + f: + li a5,32 + vsetvli zero,a5,e8,mf4,tu,ma + vle8.v v1,0(a0) + ble a3,zero,.L2 + li t0,0 + li a0,101 + .L3: + addiw t0,t0,1 + vor.vx v1,v1,a0 + vle8.v v1,0(a1) + bne a3,t0,.L3 + .L2: + vsetvli zero,zero,e8,mf4,tu,ma + vse8.v v1,0(a2) + ret + + The second vsetvli is redundant. */ + + gcc_assert (has_vtype_op (insn->rtl ())); + rinsn = PREV_INSN (insn->rtl ()); + gcc_assert (vector_config_insn_p (PREV_INSN (insn->rtl ()))); + if (m_vector_manager->all_avail_in_compatible_p (cfg_bb)) + { + size_t id = m_vector_manager->get_expr_id (info); + if (bitmap_bit_p (m_vector_manager->vector_del[cfg_bb->index], id)) + continue; + eliminate_insn (rinsn); + } + else + { + rtx new_pat + = gen_vsetvl_pat (VSETVL_VTYPE_CHANGE_ONLY, info, NULL_RTX); + change_insn (rinsn, new_pat); + } } } diff --git a/gcc/config/riscv/riscv-vsetvl.h b/gcc/config/riscv/riscv-vsetvl.h index eec03d35071..d05472c86a0 100644 --- a/gcc/config/riscv/riscv-vsetvl.h +++ b/gcc/config/riscv/riscv-vsetvl.h @@ -451,6 +451,7 @@ public: bool all_same_ratio_p (sbitmap) const; bool all_empty_predecessor_p (const basic_block) const; + bool all_avail_in_compatible_p (const basic_block) const; void release (void); void create_bitmap_vectors (void); diff --git a/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-102.c b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-102.c new file mode 100644 index 00000000000..8236d4e7f18 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/rvv/vsetvl/avl_single-102.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gcv -mabi=ilp32 -fno-schedule-insns -fno-schedule-insns2 -fno-tree-vectorize -frename-registers" } */ + +#include "riscv_vector.h" + +void f (int8_t* base1,int8_t* base2,int8_t* out,int n) +{ + vint8mf4_t v = __riscv_vle8_v_i8mf4 (base1, 32); + for (int i = 0; i < n; i++){ + v = __riscv_vor_vx_i8mf4 (v, 101, 32); + v = __riscv_vle8_v_i8mf4_tu (v, base2, 32); + } + __riscv_vse8_v_i8mf4 (out, v, 32); +} + +/* { dg-final { scan-assembler-times {vsetvli} 1 { target { no-opts "-O0" no-opts "-O1" no-opts "-Os" no-opts "-g" no-opts "-funroll-loops" } } } } */ -- 2.36.1