<yanzhang.w...@intel.com> 於 2023年7月28日 週五 19:50 寫道:

> From: Yanzhang Wang <yanzhang.w...@intel.com>
>
> 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 <yanzhang.w...@intel.com>
>
> 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" "<MODE>")])
> +
> +;;; Simplify the mulh with 0 to move
> +(define_split
> +  [(set (match_operand:VI_QHS 0 "register_operand")
> +     (if_then_else:VI_QHS
> +       (unspec:<VM>
> +        [(match_operand:<VM> 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:<VEL> 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,
> +                                            <VMULH>, <MODE>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:<VM>
> +        [(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:<VM>
> +            [(match_operand:VI 3 "register_operand")
> +              (unspec:<VM>
> +                [(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>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
>
>

Reply via email to