From: Pan Li <pan2...@intel.com> This patch would like to combine the vec_duplicate + vadd.vv to the vadd.vx. From example as below:
#define DEF_VX_BINARY(T, OP) \ void \ test_vx_binary (T * restrict out, T * restrict in, T x, unsigned n) \ { \ for (unsigned i = 0; i < n; i++) \ out[i] = in[i] OP x; \ } DEF_VX_BINARY(int32_t, +) Before this patch: 10 │ test_binary_vx_add: 11 │ beq a3,zero,.L8 12 │ vsetvli a5,zero,e32,m1,ta,ma // eliminated 13 │ vmv.v.x v2,a2 // Ditto. 14 │ slli a3,a3,32 15 │ srli a3,a3,32 16 │ .L3: 17 │ vsetvli a5,a3,e32,m1,ta,ma 18 │ vle32.v v1,0(a1) 19 │ slli a4,a5,2 20 │ sub a3,a3,a5 21 │ add a1,a1,a4 22 │ vadd.vv v1,v2,v1 23 │ vse32.v v1,0(a0) 24 │ add a0,a0,a4 25 │ bne a3,zero,.L3 After this patch: 10 │ test_binary_vx_add: 11 │ beq a3,zero,.L8 12 │ slli a3,a3,32 13 │ srli a3,a3,32 14 │ .L3: 15 │ vsetvli a5,a3,e32,m1,ta,ma 16 │ vle32.v v1,0(a1) 17 │ slli a4,a5,2 18 │ sub a3,a3,a5 19 │ add a1,a1,a4 20 │ vadd.vx v1,v1,a2 21 │ vse32.v v1,0(a0) 22 │ add a0,a0,a4 23 │ bne a3,zero,.L3 The below test suites are passed for this patch. * The rv64gcv fully regression test. gcc/ChangeLog: * config/riscv/autovec-opt.md (*<optab>_vx_<mode>): Add new combine to convert vec_duplicate + vadd.vv to vaddvx. * config/riscv/vector-iterators.md: Add new iterator for vx. Signed-off-by: Pan Li <pan2...@intel.com> --- gcc/config/riscv/autovec-opt.md | 22 ++++++++++++++++++++++ gcc/config/riscv/vector-iterators.md | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md index 4b33a145c17..6bc0388a087 100644 --- a/gcc/config/riscv/autovec-opt.md +++ b/gcc/config/riscv/autovec-opt.md @@ -1611,3 +1611,25 @@ (define_insn_and_split "*vandn_<mode>" DONE; } [(set_attr "type" "vandn")]) + +;; ============================================================================= +;; Combine vec_duplicate + op.vv to op.vx +;; Include +;; - vadd.vx +;; ============================================================================= +(define_insn_and_split "*<optab>_vx_<mode>" + [(set (match_operand:V_VLSI 0 "register_operand") + (any_int_binop_no_shift_vx:V_VLSI + (vec_duplicate:V_VLSI + (match_operand:<VEL> 1 "register_operand")) + (match_operand:V_VLSI 2 "<binop_rhs2_predicate>")))] + "TARGET_VECTOR && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] + { + rtx ops[] = {operands[0], operands[2], operands[1]}; + riscv_vector::emit_vlmax_insn (code_for_pred_scalar (<CODE>, <MODE>mode), + riscv_vector::BINARY_OP, ops); + } + [(set_attr "type" "vialu")]) diff --git a/gcc/config/riscv/vector-iterators.md b/gcc/config/riscv/vector-iterators.md index 92cb651ce49..80c184e297b 100644 --- a/gcc/config/riscv/vector-iterators.md +++ b/gcc/config/riscv/vector-iterators.md @@ -3987,6 +3987,10 @@ (define_code_iterator any_int_binop_no_shift [plus minus and ior xor smax umax smin umin mult div udiv mod umod ]) +(define_code_iterator any_int_binop_no_shift_vx + [plus +]) + (define_code_iterator any_sat_int_binop [ss_plus ss_minus us_plus us_minus]) (define_code_iterator sat_int_plus_binop [ss_plus us_plus]) (define_code_iterator sat_int_minus_binop [ss_minus us_minus]) -- 2.43.0