於 2023年7月28日 週五 19:50 寫道: > From: Yanzhang Wang > > This patch will optimize the below mulh example, > > vint32m1_t shortcut_for_riscv_vmulh_case_0(vint32m1_t v1, size_t vl) { > return __riscv_vmulh_vx_i32m1(v1, 0, vl); > } > > from mulh pattern > > vsetvli zero, a2, e32, m1, ta, ma > vmulh.vx v24, v24, zero > vs1r.v v24, 0(a0) > > to below vmv. > > vsetvli zero,a2,e32,m1,ta,ma > vmv.v.i v1,0 > vs1r.v v1,0(a0) > > It will elimate the mul with const 0 instruction to the simple mov > instruction. > > Signed-off-by: Yanzhang Wang > > gcc/ChangeLog: > > * config/riscv/autovec-opt.md: Add a split pattern. > > gcc/testsuite/ChangeLog: > > * gcc.target/riscv/rvv/base/binop_vx_constraint-121.c: The mul > with 0 will be simplified to vmv.v.i. > * gcc.target/riscv/rvv/autovec/vmulh-with-zero.cc: New test. > --- > gcc/config/riscv/autovec-opt.md | 58 +++++++++++++++++++ > gcc/config/riscv/riscv-protos.h | 2 + > gcc/config/riscv/riscv-v.cc | 57 ++++++++++++++++++ > .../riscv/rvv/autovec/vmulh-with-zero.cc | 19 ++++++ > .../riscv/rvv/base/binop_vx_constraint-121.c | 3 +- > 5 files changed, 138 insertions(+), 1 deletion(-) > create mode 100644 > gcc/testsuite/gcc.target/riscv/rvv/autovec/vmulh-with-zero.cc > > diff --git a/gcc/config/riscv/autovec-opt.md > b/gcc/config/riscv/autovec-opt.md > index 28040805b23..0d87572d1a4 100644 > --- a/gcc/config/riscv/autovec-opt.md > +++ b/gcc/config/riscv/autovec-opt.md > @@ -405,3 +405,61 @@ > "vmv.x.s\t%0,%1" > [(set_attr "type" "vimovvx") > (set_attr "mode" "")]) > + > +;;; Simplify the mulh with 0 to move > +(define_split > + [(set (match_operand:VI_QHS 0 "register_operand") > + (if_then_else:VI_QHS > + (unspec: > + [(match_operand: 1 "vector_all_trues_mask_operand") > + (match_operand 5 "vector_length_operand") > + (match_operand 6 "const_int_operand") > + (match_operand 7 "const_int_operand") > + (match_operand 8 "const_int_operand") > + (reg:SI VL_REGNUM) > + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) > + (unspec:VI_QHS > + [(vec_duplicate:VI_QHS > + (match_operand: 4 "reg_or_0_operand")) > This could be just a const int zero rather than a match operand + (match_operand:VI_QHS 3 "register_operand")] VMULH) > + (match_operand:VI_QHS 2 "vector_merge_operand") > + ))] > + "TARGET_VECTOR > + && rtx_equal_p (operands[4], CONST0_RTX (GET_MODE (operands[4])))" > Then no need to check here. + [(const_int 0)] > +{ > + riscv_vector::simplify_unspec_operations (operands, UNSPEC, > + , mode) ; > + DONE; > +}) > + > +;;; Simplify vmadc + vadc with 0 to a simple move. > +(define_split > + [(set (match_operand:VI 0 "register_operand") > + (if_then_else:VI > + (unspec: > + [(match_operand 4 "vector_length_operand") > + (match_operand 5 "const_int_operand") > + (match_operand 6 "const_int_operand") > + (reg:SI VL_REGNUM) > + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) > + (unspec:VI > + [(match_operand:VI 2 "register_operand") > + (unspec: > + [(match_operand:VI 3 "register_operand") > + (unspec: > + [(match_operand 7 "vector_length_operand") > + (match_operand 8 "const_int_operand") > + (reg:SI VL_REGNUM) > + (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE) > + ] UNSPEC_OVERFLOW) > + ] UNSPEC_VADC) > + (match_operand:VI 1 "vector_merge_operand")))] > + "TARGET_VECTOR" > + [(const_int 0)] > +{ > + riscv_vector::simplify_unspec_operations (operands, PLUS, UNSPEC_VADC, > + mode); > + DONE; > +}) > + > diff --git a/gcc/config/riscv/riscv-protos.h > b/gcc/config/riscv/riscv-protos.h > index f052757cede..6a188a3d0ef 100644 > --- a/gcc/config/riscv/riscv-protos.h > +++ b/gcc/config/riscv/riscv-protos.h > @@ -228,6 +228,8 @@ bool neg_simm5_p (rtx); > bool has_vi_variant_p (rtx_code, rtx); > void expand_vec_cmp (rtx, rtx_code, rtx, rtx); > bool expand_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool); > +void simplify_complement (rtx *, rtx_code, machine_mode); > +void simplify_unspec_operations (rtx*, rtx_code, int, machine_mode); > #endif > bool sew64_scalar_helper (rtx *, rtx *, rtx, machine_mode, > bool, void (*)(rtx *, rtx)); > diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc > index 839a2c6ba71..9a9428ce18d 100644 > --- a/gcc/config/riscv/riscv-v.cc > +++ b/gcc/config/riscv/riscv-v.cc > @@ -2721,4 +2721,61 @@ expand_select_vl (rtx *ops) > emit_insn (gen_no_side_effects_vsetvl_rtx (rvv_mode, ops[0], ops[1])); > } > > +void simplify_mulh (rtx *operands, > + machine_mode mode) > +{ > + rtx zero_operand = CONST0_RTX(GET_MODE(operands[4])); > + if (rtx_equal_p(operands[4], zero_operand)) > + { > + machine_mode mask_mode = riscv_vector::get_mask_mode (mode).require > (); > + emit_insn (gen_pred_mov (mode, operands[0], CONST1_RTX (mask_mode), > + RVV_VUNDEF (mode), > + CONST0_RTX (GET_MODE (operands[0])), > + operands[5], operands[6], operands[7], > + operands[8])); > + } > +} > + > +void simplify_vadc (rtx *operands, > + machine_mode mode) > +{ > + machine_mode mask_mode = riscv_vector::get_mask_mode (mode).require (); > + > + if (rtx_equal_p(operands[2], operands[3])) > + { > + emit_insn (gen_pred_mov (mode, operands[0], CONST1_RTX (mask_mode), > + operands[1], operands[2], operands[4], > + operands[5], operands[6], > + get_avl_type_rtx (riscv_vector::VLMAX))); > + } > +} > + > +void simplify_unspec_operations (rtx *operands, > + rtx_code code, > + int unspec, > + machine_mode mode) > +{ > + switch (unspec) > + { > + case UNSPEC_VMULHS: > + case UNSPEC_VMULHU: > + case UNSPEC_VMULHSU: > + simplify_mulh (operands, mode); > + break; > + > + case UNSPEC_VADC: > + case UNSPEC_VSBC: > + simplify_vadc(operands, mode); > + break; > + > + default: > + break; > + } > +} > + > +void simplify_complement (rtx *operands, > + rtx_code code, > + machine_mode mode) > +{ > +} > } // namespace riscv_vector > diff --git a/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmulh-with-zero.cc > b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmulh-with-zero.cc > new file mode 100644 > index 00000000000..6e4a3d62bc0 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/riscv/rvv/autovec/vmulh-with-zero.cc > @@ -0,0 +1,19 @@ > +/* { dg-do compile } */ > +/* { dg-options "-march=rv64gcv -mabi=lp64 -O3 -Wno-psabi" } */ > + > +#include "riscv_vector.h" > + > +#define VMULH_WITH_LMUL(X) \ > + vint32m##X##_t shortcut_for_riscv_vmulh_case_##X (vint32m##X##_t v1,\ > + size_t vl) { \ > + return __riscv_vmulh_vx_i32m ##X (v1, 0, vl); > \ > + } > + > + > +VMULH_WITH_LMUL (1) > +VMULH_WITH_LMUL (2) > +VMULH_WITH_LMUL (4) > +VMULH_WITH_LMUL (8) > +VMULH_WITH_LMUL (f2) > + > +/* { dg-final { scan-assembler-times {vmv\.v\.i\sv[0-9]+,0} 5} */ > diff --git > a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-121.c > b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-121.c > index 4d2de91bc14..d1473274137 100644 > --- a/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-121.c > +++ b/gcc/testsuite/gcc.target/riscv/rvv/base/binop_vx_constraint-121.c > @@ -50,6 +50,7 @@ void f6 (void * in, void *out, int32_t x) > __riscv_vse64_v_i64m1 (out, v3, 4); > } > > -/* { dg-final { scan-assembler-times > {vmulh\.vx\s+v[0-9]+,\s*v[0-9]+,zero} 2 } } */ > +/* { dg-final { scan-assembler-times {vmv\.v\.i\sv[0-9]+,0} 1 } } */ > +/* { dg-final { scan-assembler-times > {vmulh\.vx\s+v[0-9]+,\s*v[0-9]+,zero} 1 } } */ > /* { dg-final { scan-assembler-times {vdiv\.vx\s+v[0-9]+,\s*v[0-9]+,zero} > 2 } } */ > /* { dg-final { scan-assembler-times {vrem\.vx\s+v[0-9]+,\s*v[0-9]+,zero} > 2 } } */ > -- > 2.41.0 > >