Hi Robin and Juzhe, Just took a look and I like the approach. On 4/26/23 19:43, juzhe.zhong wrote: > Yeah,Robin stuff is what I want and is making perfect sense for me. > ---- Replied Message ---- > From Robin Dapp > Date 04/27/2023 02:15 > To juzhe.zhong@rivai.ai > , > collison , > gcc-patches > Cc jeffreyalaw , > Kito.cheng , > kito.cheng , > palmer , > palmer > Subject Re: [PATCH v4 05/10] RISC-V:autovec: Add autovectorization > patterns for binary integer operations > > Hi Michael, > > I have the diff below for the binops in my tree locally. > Maybe something like this works for you? Untested but compiles and > the expander helpers would need to be fortified obviously. > > Regards > Robin > > -- > > gcc/ChangeLog: > >        * config/riscv/autovec.md (3): New binops expander. >        * config/riscv/riscv-protos.h (emit_nonvlmax_binop): Define. >        * config/riscv/riscv-v.cc (emit_pred_binop): New function. >        (emit_nonvlmax_binop): New function. >        * config/riscv/vector-iterators.md: New iterator. > --- > gcc/config/riscv/autovec.md          | 12 ++++ > gcc/config/riscv/riscv-protos.h      |  1 + > gcc/config/riscv/riscv-v.cc          | 89 ++++++++++++++++++++-------- > gcc/config/riscv/vector-iterators.md | 20 +++++++ > 4 files changed, 97 insertions(+), 25 deletions(-) > > diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md > index b5d46ff57ab..c21d241f426 100644 > --- a/gcc/config/riscv/autovec.md > +++ b/gcc/config/riscv/autovec.md > @@ -47,3 +47,15 @@ (define_expand "len_store_" >                  operands[1], operands[2], mode); >   DONE; > }) > + > +(define_expand "3" > +  [(set (match_operand:VI 0 "register_operand") > +    (any_int_binop:VI (match_operand:VI 1 "register_operand") > +              (match_operand:VI 2 "register_operand")))] > +  "TARGET_VECTOR" > +{ > +  riscv_vector::emit_nonvlmax_binop (code_for_pred (, > mode), > +                     operands[0], operands[1], operands[2], > +                     gen_reg_rtx (Pmode), mode); > +  DONE; > +}) > diff --git a/gcc/config/riscv/riscv-protos.h > b/gcc/config/riscv/riscv-protos.h > index f6ea6846736..5cca543c773 100644 > --- a/gcc/config/riscv/riscv-protos.h > +++ b/gcc/config/riscv/riscv-protos.h > @@ -163,6 +163,7 @@ void emit_hard_vlmax_vsetvl (machine_mode, rtx); > void emit_vlmax_op (unsigned, rtx, rtx, machine_mode); > void emit_vlmax_op (unsigned, rtx, rtx, rtx, machine_mode); > void emit_nonvlmax_op (unsigned, rtx, rtx, rtx, machine_mode); > +void emit_nonvlmax_binop (unsigned, rtx, rtx, rtx, rtx, machine_mode); > enum vlmul_type get_vlmul (machine_mode); > unsigned int get_ratio (machine_mode); > int get_ta (rtx); > diff --git a/gcc/config/riscv/riscv-v.cc b/gcc/config/riscv/riscv-v.cc > index 5e69427ac54..98ebc052340 100644 > --- a/gcc/config/riscv/riscv-v.cc > +++ b/gcc/config/riscv/riscv-v.cc > @@ -52,7 +52,7 @@ namespace riscv_vector { > template class insn_expander > { > public: > -  insn_expander () : m_opno (0) {} > +  insn_expander () : m_opno (0), has_dest(false) {} >   void add_output_operand (rtx x, machine_mode mode) >   { >     create_output_operand (&m_ops[m_opno++], x, mode); > @@ -83,6 +83,44 @@ public: >     add_input_operand (gen_int_mode (type, Pmode), Pmode); >   } > > +  void set_dest_and_mask (rtx mask, rtx dest, machine_mode mask_mode) > +  { > +    dest_mode = GET_MODE (dest); > +    has_dest = true; > + > +    add_output_operand (dest, dest_mode); > + > +    if (mask) > +      add_input_operand (mask, GET_MODE (mask)); > +    else > +      add_all_one_mask_operand (mask_mode); > + > +    add_vundef_operand (dest_mode); > +  } > + > +  void set_len_and_policy (rtx len, bool vlmax_p) > +    { > +      gcc_assert (has_dest); > +      gcc_assert (len || vlmax_p); > + > +      if (len) > +    add_input_operand (len, Pmode); > +      else > +    { > +      rtx vlmax = gen_reg_rtx (Pmode); > +      emit_vlmax_vsetvl (dest_mode, vlmax); > +      add_input_operand (vlmax, Pmode); > +    } > + > +      if (GET_MODE_CLASS (dest_mode) != MODE_VECTOR_BOOL) > +    add_policy_operand (get_prefer_tail_policy (), > get_prefer_mask_policy ()); > + > +      if (vlmax_p) > +    add_avl_type_operand (avl_type::VLMAX); > +      else > +    add_avl_type_operand (avl_type::NONVLMAX); > +    } > + >   void expand (enum insn_code icode, bool temporary_volatile_p = false) >   { >     if (temporary_volatile_p) > @@ -96,6 +134,8 @@ public: > > private: >   int m_opno; > +  bool has_dest; > +  machine_mode dest_mode; >   expand_operand m_ops[MAX_OPERANDS]; > }; > > @@ -183,37 +223,29 @@ emit_pred_op (unsigned icode, rtx mask, rtx > dest, rtx src, rtx len, >          machine_mode mask_mode, bool vlmax_p) > { >   insn_expander<8> e; > -  machine_mode mode = GET_MODE (dest); > +  e.set_dest_and_mask (mask, dest, mask_mode); > > -  e.add_output_operand (dest, mode); > - > -  if (mask) > -    e.add_input_operand (mask, GET_MODE (mask)); > -  else > -    e.add_all_one_mask_operand (mask_mode); > +  e.add_input_operand (src, GET_MODE (src)); > > -  e.add_vundef_operand (mode); > +  e.set_len_and_policy (len, vlmax_p); > > -  e.add_input_operand (src, GET_MODE (src)); > +  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src)); > +} > > -  if (len) > -    e.add_input_operand (len, Pmode); > -  else > -    { > -      rtx vlmax = gen_reg_rtx (Pmode); > -      emit_vlmax_vsetvl (mode, vlmax); > -      e.add_input_operand (vlmax, Pmode); > -    } > +/* Emit an RVV unmask && vl mov from SRC to DEST.  */ > +static void > +emit_pred_binop (unsigned icode, rtx mask, rtx dest, rtx src1, rtx src2, > +         rtx len, machine_mode mask_mode, bool vlmax_p) > +{ > +  insn_expander<9> e; > +  e.set_dest_and_mask (mask, dest, mask_mode); > > -  if (GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL) > -    e.add_policy_operand (get_prefer_tail_policy (), > get_prefer_mask_policy ()); > +  e.add_input_operand (src1, GET_MODE (src1)); > +  e.add_input_operand (src2, GET_MODE (src2)); > > -  if (vlmax_p) > -    e.add_avl_type_operand (avl_type::VLMAX); > -  else > -    e.add_avl_type_operand (avl_type::NONVLMAX); > +  e.set_len_and_policy (len, vlmax_p); > > -  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src)); > +  e.expand ((enum insn_code) icode, MEM_P (dest) || MEM_P (src1) || > MEM_P (src2)); > } > > void > @@ -236,6 +268,13 @@ emit_nonvlmax_op (unsigned icode, rtx dest, rtx > src, rtx len, >   emit_pred_op (icode, NULL_RTX, dest, src, len, mask_mode, false); > } > > +void > +emit_nonvlmax_binop (unsigned icode, rtx dest, rtx src1, rtx src2, > rtx len, > +             machine_mode mask_mode) > +{ > +  emit_pred_binop (icode, NULL_RTX, dest, src1, src2, len, mask_mode, > false); > +} > + > static void > expand_const_vector (rtx target, rtx src, machine_mode mask_mode) > { > diff --git a/gcc/config/riscv/vector-iterators.md > b/gcc/config/riscv/vector-iterators.md > index a8e856161d3..7cf21751d2f 100644 > --- a/gcc/config/riscv/vector-iterators.md > +++ b/gcc/config/riscv/vector-iterators.md > @@ -934,6 +934,26 @@ (define_code_iterator any_int_binop [plus minus > and ior xor ashift ashiftrt lshi >   smax umax smin umin mult div udiv mod umod > ]) > > +(define_code_attr ANY_INT_BINOP [ > +    (plus "PLUS") > +    (minus "MINUS") > +    (and "AND") > +    (ior "IOR") > +    (xor "XOR") > +    (ashift "ASHIFT") > +    (ashiftrt "ASHIFTRT") > +    (lshiftrt "LSHIFTRT") > +    (smax "SMAX") > +    (umax "UMAX") > +    (smin "SMIN") > +    (umin "UMIN") > +    (mult "MULT") > +    (div "DIV") > +    (udiv "UDIV") > +    (mod "MOD") > +    (umod "UMOD") > +]) > + > (define_code_iterator any_int_unop [neg not]) > > (define_code_iterator any_commutative_binop [plus and ior xor > -- > 2.40.0 >