RISC-V: Refactor expand_reduction and cleanup enum reduction_type

Message ID 20230915050613.22696-1-lehua.ding@rivai.ai
State Unresolved
Headers
Series RISC-V: Refactor expand_reduction and cleanup enum reduction_type |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Lehua Ding Sept. 15, 2023, 5:06 a.m. UTC
  This patch refactors expand_reduction, remove the reduction_type argument
and add insn_flags argument to determine the passing of the operands.
ops has also been modified to restrict it to only two cases and to remove
operand that are not in use.

gcc/ChangeLog:

	* config/riscv/autovec-opt.md: Adjust.
	* config/riscv/autovec.md: Ditto.
	* config/riscv/riscv-protos.h (enum class): Delete enum reduction_type.
	(expand_reduction): Adjust expand_reduction prototype.
	* config/riscv/riscv-v.cc (need_mask_operand_p): New helper function.
	(expand_reduction): Refactor expand_reduction.

---
 gcc/config/riscv/autovec-opt.md | 22 +++++++-----
 gcc/config/riscv/autovec.md     | 51 ++++++++++++++++++----------
 gcc/config/riscv/riscv-protos.h |  9 +----
 gcc/config/riscv/riscv-v.cc     | 60 +++++++++++++++++----------------
 4 files changed, 79 insertions(+), 63 deletions(-)

--
2.36.3
  

Comments

Kito Cheng Sept. 15, 2023, 8:46 a.m. UTC | #1
LGTM

On Fri, Sep 15, 2023 at 1:06 PM Lehua Ding <lehua.ding@rivai.ai> wrote:

> This patch refactors expand_reduction, remove the reduction_type argument
> and add insn_flags argument to determine the passing of the operands.
> ops has also been modified to restrict it to only two cases and to remove
> operand that are not in use.
>
> gcc/ChangeLog:
>
>         * config/riscv/autovec-opt.md: Adjust.
>         * config/riscv/autovec.md: Ditto.
>         * config/riscv/riscv-protos.h (enum class): Delete enum
> reduction_type.
>         (expand_reduction): Adjust expand_reduction prototype.
>         * config/riscv/riscv-v.cc (need_mask_operand_p): New helper
> function.
>         (expand_reduction): Refactor expand_reduction.
>
> ---
>  gcc/config/riscv/autovec-opt.md | 22 +++++++-----
>  gcc/config/riscv/autovec.md     | 51 ++++++++++++++++++----------
>  gcc/config/riscv/riscv-protos.h |  9 +----
>  gcc/config/riscv/riscv-v.cc     | 60 +++++++++++++++++----------------
>  4 files changed, 79 insertions(+), 63 deletions(-)
>
> diff --git a/gcc/config/riscv/autovec-opt.md
> b/gcc/config/riscv/autovec-opt.md
> index df516849527..b47bae16193 100644
> --- a/gcc/config/riscv/autovec-opt.md
> +++ b/gcc/config/riscv/autovec-opt.md
> @@ -1208,7 +1208,8 @@
>    "&& 1"
>    [(const_int 0)]
>  {
> -  riscv_vector::expand_reduction (<WREDUC_UNSPEC>, operands,
> +  riscv_vector::expand_reduction (<WREDUC_UNSPEC>,
> riscv_vector::REDUCE_OP,
> +                                  operands,
>                                    CONST0_RTX (<V_DOUBLE_EXTEND_VEL>mode));
>    DONE;
>  }
> @@ -1226,7 +1227,9 @@
>    "&& 1"
>    [(const_int 0)]
>  {
> -  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_UNORDERED, operands,
> +  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_UNORDERED,
> +                                  riscv_vector::REDUCE_OP_FRM_DYN,
> +                                  operands,
>                                    CONST0_RTX (<V_DOUBLE_EXTEND_VEL>mode));
>    DONE;
>  }
> @@ -1245,9 +1248,9 @@
>    "&& 1"
>    [(const_int 0)]
>  {
> -  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED, operands,
> -                                 operands[1],
> -                                 riscv_vector::reduction_type::FOLD_LEFT);
> +  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED,
> +                                  riscv_vector::REDUCE_OP_FRM_DYN,
> +                                  operands, operands[1]);
>    DONE;
>  }
>  [(set_attr "type" "vector")])
> @@ -1271,9 +1274,12 @@
>    if (rtx_equal_p (operands[4], const0_rtx))
>      emit_move_insn (operands[0], operands[1]);
>    else
> -    riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED, operands,
> -                                   operands[1],
> -
>  riscv_vector::reduction_type::MASK_LEN_FOLD_LEFT);
> +    {
> +      rtx ops[] = {operands[0], operands[2], operands[3], operands[4]};
> +      riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED,
> +                                      riscv_vector::REDUCE_OP_M_FRM_DYN,
> +                                      ops, operands[1]);
> +    }
>    DONE;
>  }
>  [(set_attr "type" "vector")])
> diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
> index 8537b9d41f6..c6175a3b1f6 100644
> --- a/gcc/config/riscv/autovec.md
> +++ b/gcc/config/riscv/autovec.md
> @@ -2096,7 +2096,8 @@
>    "&& 1"
>    [(const_int 0)]
>  {
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM, operands, CONST0_RTX
> (<VEL>mode));
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM,
> riscv_vector::REDUCE_OP,
> +                                  operands, CONST0_RTX (<VEL>mode));
>    DONE;
>  }
>  [(set_attr "type" "vector")])
> @@ -2108,7 +2109,8 @@
>  {
>    int prec = GET_MODE_PRECISION (<VEL>mode);
>    rtx min = immed_wide_int_const (wi::min_value (prec, SIGNED),
> <VEL>mode);
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, operands, min);
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX,
> riscv_vector::REDUCE_OP,
> +                                  operands, min);
>    DONE;
>  })
>
> @@ -2117,7 +2119,8 @@
>     (match_operand:VI 1 "register_operand")]
>    "TARGET_VECTOR"
>  {
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_MAXU, operands, CONST0_RTX
> (<VEL>mode));
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_MAXU,
> riscv_vector::REDUCE_OP,
> +                                  operands, CONST0_RTX (<VEL>mode));
>    DONE;
>  })
>
> @@ -2128,7 +2131,8 @@
>  {
>    int prec = GET_MODE_PRECISION (<VEL>mode);
>    rtx max = immed_wide_int_const (wi::max_value (prec, SIGNED),
> <VEL>mode);
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, operands, max);
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN,
> riscv_vector::REDUCE_OP,
> +                                  operands, max);
>    DONE;
>  })
>
> @@ -2139,7 +2143,8 @@
>  {
>    int prec = GET_MODE_PRECISION (<VEL>mode);
>    rtx max = immed_wide_int_const (wi::max_value (prec, UNSIGNED),
> <VEL>mode);
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_MINU, operands, max);
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_MINU,
> riscv_vector::REDUCE_OP,
> +                                  operands, max);
>    DONE;
>  })
>
> @@ -2148,7 +2153,8 @@
>     (match_operand:VI 1 "register_operand")]
>    "TARGET_VECTOR"
>  {
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_AND, operands, CONSTM1_RTX
> (<VEL>mode));
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_AND,
> riscv_vector::REDUCE_OP,
> +                                  operands, CONSTM1_RTX (<VEL>mode));
>    DONE;
>  })
>
> @@ -2157,7 +2163,8 @@
>     (match_operand:VI 1 "register_operand")]
>    "TARGET_VECTOR"
>  {
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_OR, operands, CONST0_RTX
> (<VEL>mode));
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_OR,
> riscv_vector::REDUCE_OP,
> +                                  operands, CONST0_RTX (<VEL>mode));
>    DONE;
>  })
>
> @@ -2166,7 +2173,8 @@
>     (match_operand:VI 1 "register_operand")]
>    "TARGET_VECTOR"
>  {
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_XOR, operands, CONST0_RTX
> (<VEL>mode));
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_XOR,
> riscv_vector::REDUCE_OP,
> +                                  operands, CONST0_RTX (<VEL>mode));
>    DONE;
>  })
>
> @@ -2189,8 +2197,9 @@
>    "&& 1"
>    [(const_int 0)]
>  {
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_UNORDERED, operands,
> -                                  CONST0_RTX (<VEL>mode));
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_UNORDERED,
> +                                  riscv_vector::REDUCE_OP_FRM_DYN,
> +                                  operands, CONST0_RTX (<VEL>mode));
>    DONE;
>  }
>  [(set_attr "type" "vector")])
> @@ -2203,7 +2212,8 @@
>    REAL_VALUE_TYPE rv;
>    real_inf (&rv, true);
>    rtx f = const_double_from_real_value (rv, <VEL>mode);
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, operands, f);
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX,
> riscv_vector::REDUCE_OP,
> +                                  operands, f);
>    DONE;
>  })
>
> @@ -2215,7 +2225,8 @@
>    REAL_VALUE_TYPE rv;
>    real_inf (&rv, false);
>    rtx f = const_double_from_real_value (rv, <VEL>mode);
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, operands, f);
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN,
> riscv_vector::REDUCE_OP,
> +                                  operands, f);
>    DONE;
>  })
>
> @@ -2238,9 +2249,10 @@
>    "&& 1"
>    [(const_int 0)]
>  {
> -  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED, operands,
> -                                 operands[1],
> -                                 riscv_vector::reduction_type::FOLD_LEFT);
> +  rtx ops[] = {operands[0], operands[2]};
> +  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED,
> +                                  riscv_vector::REDUCE_OP_FRM_DYN,
> +                                  ops, operands[1]);
>    DONE;
>  }
>  [(set_attr "type" "vector")])
> @@ -2263,9 +2275,12 @@
>    if (rtx_equal_p (operands[4], const0_rtx))
>      emit_move_insn (operands[0], operands[1]);
>    else
> -    riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED, operands,
> -                                   operands[1],
> -
>  riscv_vector::reduction_type::MASK_LEN_FOLD_LEFT);
> +    {
> +      rtx ops[] = {operands[0], operands[2], operands[3], operands[4]};
> +      riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED,
> +                                      riscv_vector::REDUCE_OP_M_FRM_DYN,
> +                                      ops, operands[1]);
> +    }
>    DONE;
>  }
>  [(set_attr "type" "vector")])
> diff --git a/gcc/config/riscv/riscv-protos.h
> b/gcc/config/riscv/riscv-protos.h
> index 44fa36c32ab..bb94a7e0441 100644
> --- a/gcc/config/riscv/riscv-protos.h
> +++ b/gcc/config/riscv/riscv-protos.h
> @@ -414,12 +414,6 @@ enum mask_policy
>  /* Return true if VALUE is agnostic or any policy.  */
>  #define IS_AGNOSTIC(VALUE) (bool) (VALUE & 0x1 || (VALUE >> 1 & 0x1))
>
> -enum class reduction_type
> -{
> -  UNORDERED,
> -  FOLD_LEFT,
> -  MASK_LEN_FOLD_LEFT,
> -};
>  enum tail_policy get_prefer_tail_policy ();
>  enum mask_policy get_prefer_mask_policy ();
>  rtx get_avl_type_rtx (enum avl_type);
> @@ -433,8 +427,7 @@ void expand_vec_cmp (rtx, rtx_code, rtx, rtx);
>  bool expand_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool);
>  void expand_cond_len_unop (unsigned, rtx *);
>  void expand_cond_len_binop (unsigned, rtx *);
> -void expand_reduction (unsigned, rtx *, rtx,
> -                      reduction_type = reduction_type::UNORDERED);
> +void expand_reduction (unsigned, unsigned, rtx *, rtx);
>  #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 668594b65ed..7e9fd9ec741 100644
> --- a/gcc/config/riscv/riscv-v.cc
> +++ b/gcc/config/riscv/riscv-v.cc
> @@ -67,6 +67,18 @@ const_vlmax_p (machine_mode mode)
>      : false;
>  }
>
> +/* Helper functions for insn_flags && insn_types */
> +
> +/* Return true if caller need pass mask operand for insn pattern with
> +   INSN_FLAGS. */
> +
> +static bool
> +need_mask_operand_p (unsigned insn_flags)
> +{
> +  return (insn_flags & HAS_MASK_P)
> +        && !(insn_flags & (USE_ONE_TRUE_MASK_P | USE_ALL_TRUES_MASK_P));
> +}
> +
>  template <int MAX_OPERANDS> class insn_expander
>  {
>  public:
> @@ -3206,48 +3218,38 @@ expand_cond_len_ternop (unsigned icode, rtx *ops)
>    expand_cond_len_op (icode, TERNARY_OP_P, cond_ops, len);
>  }
>
> -/* Expand reduction operations.  */
> +/* Expand reduction operations.
> +     Case 1: ops = {scalar_dest, vector_src}
> +     Case 2: ops = {scalar_dest, vector_src, mask, vl}
> +*/
>  void
> -expand_reduction (unsigned unspec, rtx *ops, rtx init, reduction_type
> type)
> +expand_reduction (unsigned unspec, unsigned insn_flags, rtx *ops, rtx
> init)
>  {
> -  rtx vector = type == reduction_type::UNORDERED ? ops[1] : ops[2];
> -  machine_mode vmode = GET_MODE (vector);
> -  machine_mode vel_mode = GET_MODE (ops[0]);
> +  rtx scalar_dest = ops[0];
> +  rtx vector_src = ops[1];
> +  machine_mode vmode = GET_MODE (vector_src);
> +  machine_mode vel_mode = GET_MODE (scalar_dest);
>    machine_mode m1_mode = get_m1_mode (vel_mode).require ();
>
>    rtx m1_tmp = gen_reg_rtx (m1_mode);
>    rtx scalar_move_ops[] = {m1_tmp, init};
>    emit_nonvlmax_insn (code_for_pred_broadcast (m1_mode), SCALAR_MOVE_OP,
> -                      scalar_move_ops,
> -                      type == reduction_type::MASK_LEN_FOLD_LEFT
> -                        ? ops[4]
> -                        : CONST1_RTX (Pmode));
> +                     scalar_move_ops,
> +                     need_mask_operand_p (insn_flags) ? ops[3]
> +                                                      : CONST1_RTX
> (Pmode));
>    rtx m1_tmp2 = gen_reg_rtx (m1_mode);
> -  rtx reduc_ops[] = {m1_tmp2, vector, m1_tmp};
> +  rtx reduc_ops[] = {m1_tmp2, vector_src, m1_tmp};
> +  insn_code icode = code_for_pred (unspec, vmode);
>
> -  if (unspec == UNSPEC_REDUC_SUM_ORDERED
> -      || unspec == UNSPEC_WREDUC_SUM_ORDERED
> -      || unspec == UNSPEC_REDUC_SUM_UNORDERED
> -      || unspec == UNSPEC_WREDUC_SUM_UNORDERED)
> +  if (need_mask_operand_p (insn_flags))
>      {
> -      insn_code icode = code_for_pred (unspec, vmode);
> -      if (type == reduction_type::MASK_LEN_FOLD_LEFT)
> -       {
> -         rtx mask = ops[3];
> -         rtx mask_len_reduc_ops[] = {m1_tmp2, mask, vector, m1_tmp};
> -         emit_nonvlmax_insn (icode, REDUCE_OP_M_FRM_DYN,
> mask_len_reduc_ops,
> -                              ops[4]);
> -       }
> -      else
> -       emit_vlmax_insn (icode, REDUCE_OP_FRM_DYN, reduc_ops);
> +      rtx mask_len_reduc_ops[] = {m1_tmp2, ops[2], vector_src, m1_tmp};
> +      emit_nonvlmax_insn (icode, insn_flags, mask_len_reduc_ops, ops[3]);
>      }
>    else
> -    {
> -      insn_code icode = code_for_pred (unspec, vmode);
> -      emit_vlmax_insn (icode, REDUCE_OP, reduc_ops);
> -    }
> +    emit_vlmax_insn (icode, insn_flags, reduc_ops);
>
> -  emit_insn (gen_pred_extract_first (m1_mode, ops[0], m1_tmp2));
> +  emit_insn (gen_pred_extract_first (m1_mode, scalar_dest, m1_tmp2));
>  }
>
>  /* Prepare ops for ternary operations.
> --
> 2.36.3
>
>
  
Lehua Ding Sept. 15, 2023, 10:19 a.m. UTC | #2
Committed, thanks Kito.

On 2023/9/15 16:46, Kito Cheng wrote:
> LGTM
> 
> On Fri, Sep 15, 2023 at 1:06 PM Lehua Ding <lehua.ding@rivai.ai 
> <mailto:lehua.ding@rivai.ai>> wrote:
> 
>     This patch refactors expand_reduction, remove the reduction_type
>     argument
>     and add insn_flags argument to determine the passing of the operands.
>     ops has also been modified to restrict it to only two cases and to
>     remove
>     operand that are not in use.
> 
>     gcc/ChangeLog:
> 
>              * config/riscv/autovec-opt.md: Adjust.
>              * config/riscv/autovec.md: Ditto.
>              * config/riscv/riscv-protos.h (enum class): Delete enum
>     reduction_type.
>              (expand_reduction): Adjust expand_reduction prototype.
>              * config/riscv/riscv-v.cc (need_mask_operand_p): New helper
>     function.
>              (expand_reduction): Refactor expand_reduction.
> 
>     ---
>       gcc/config/riscv/autovec-opt.md | 22 +++++++-----
>       gcc/config/riscv/autovec.md     | 51 ++++++++++++++++++----------
>       gcc/config/riscv/riscv-protos.h |  9 +----
>       gcc/config/riscv/riscv-v.cc     | 60 +++++++++++++++++----------------
>       4 files changed, 79 insertions(+), 63 deletions(-)
> 
>     diff --git a/gcc/config/riscv/autovec-opt.md
>     b/gcc/config/riscv/autovec-opt.md
>     index df516849527..b47bae16193 100644
>     --- a/gcc/config/riscv/autovec-opt.md
>     +++ b/gcc/config/riscv/autovec-opt.md
>     @@ -1208,7 +1208,8 @@
>         "&& 1"
>         [(const_int 0)]
>       {
>     -  riscv_vector::expand_reduction (<WREDUC_UNSPEC>, operands,
>     +  riscv_vector::expand_reduction (<WREDUC_UNSPEC>,
>     riscv_vector::REDUCE_OP,
>     +                                  operands,
>                                         CONST0_RTX
>     (<V_DOUBLE_EXTEND_VEL>mode));
>         DONE;
>       }
>     @@ -1226,7 +1227,9 @@
>         "&& 1"
>         [(const_int 0)]
>       {
>     -  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_UNORDERED,
>     operands,
>     +  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_UNORDERED,
>     +                                  riscv_vector::REDUCE_OP_FRM_DYN,
>     +                                  operands,
>                                         CONST0_RTX
>     (<V_DOUBLE_EXTEND_VEL>mode));
>         DONE;
>       }
>     @@ -1245,9 +1248,9 @@
>         "&& 1"
>         [(const_int 0)]
>       {
>     -  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED, operands,
>     -                                 operands[1],
>     -                               
>       riscv_vector::reduction_type::FOLD_LEFT);
>     +  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED,
>     +                                  riscv_vector::REDUCE_OP_FRM_DYN,
>     +                                  operands, operands[1]);
>         DONE;
>       }
>       [(set_attr "type" "vector")])
>     @@ -1271,9 +1274,12 @@
>         if (rtx_equal_p (operands[4], const0_rtx))
>           emit_move_insn (operands[0], operands[1]);
>         else
>     -    riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED,
>     operands,
>     -                                   operands[1],
>     -                                 
>       riscv_vector::reduction_type::MASK_LEN_FOLD_LEFT);
>     +    {
>     +      rtx ops[] = {operands[0], operands[2], operands[3], operands[4]};
>     +      riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED,
>     +                                     
>     riscv_vector::REDUCE_OP_M_FRM_DYN,
>     +                                      ops, operands[1]);
>     +    }
>         DONE;
>       }
>       [(set_attr "type" "vector")])
>     diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
>     index 8537b9d41f6..c6175a3b1f6 100644
>     --- a/gcc/config/riscv/autovec.md
>     +++ b/gcc/config/riscv/autovec.md
>     @@ -2096,7 +2096,8 @@
>         "&& 1"
>         [(const_int 0)]
>       {
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM, operands,
>     CONST0_RTX (<VEL>mode));
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM,
>     riscv_vector::REDUCE_OP,
>     +                                  operands, CONST0_RTX (<VEL>mode));
>         DONE;
>       }
>       [(set_attr "type" "vector")])
>     @@ -2108,7 +2109,8 @@
>       {
>         int prec = GET_MODE_PRECISION (<VEL>mode);
>         rtx min = immed_wide_int_const (wi::min_value (prec, SIGNED),
>     <VEL>mode);
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, operands, min);
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX,
>     riscv_vector::REDUCE_OP,
>     +                                  operands, min);
>         DONE;
>       })
> 
>     @@ -2117,7 +2119,8 @@
>          (match_operand:VI 1 "register_operand")]
>         "TARGET_VECTOR"
>       {
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_MAXU, operands,
>     CONST0_RTX (<VEL>mode));
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_MAXU,
>     riscv_vector::REDUCE_OP,
>     +                                  operands, CONST0_RTX (<VEL>mode));
>         DONE;
>       })
> 
>     @@ -2128,7 +2131,8 @@
>       {
>         int prec = GET_MODE_PRECISION (<VEL>mode);
>         rtx max = immed_wide_int_const (wi::max_value (prec, SIGNED),
>     <VEL>mode);
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, operands, max);
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN,
>     riscv_vector::REDUCE_OP,
>     +                                  operands, max);
>         DONE;
>       })
> 
>     @@ -2139,7 +2143,8 @@
>       {
>         int prec = GET_MODE_PRECISION (<VEL>mode);
>         rtx max = immed_wide_int_const (wi::max_value (prec, UNSIGNED),
>     <VEL>mode);
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_MINU, operands, max);
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_MINU,
>     riscv_vector::REDUCE_OP,
>     +                                  operands, max);
>         DONE;
>       })
> 
>     @@ -2148,7 +2153,8 @@
>          (match_operand:VI 1 "register_operand")]
>         "TARGET_VECTOR"
>       {
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_AND, operands,
>     CONSTM1_RTX (<VEL>mode));
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_AND,
>     riscv_vector::REDUCE_OP,
>     +                                  operands, CONSTM1_RTX (<VEL>mode));
>         DONE;
>       })
> 
>     @@ -2157,7 +2163,8 @@
>          (match_operand:VI 1 "register_operand")]
>         "TARGET_VECTOR"
>       {
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_OR, operands,
>     CONST0_RTX (<VEL>mode));
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_OR,
>     riscv_vector::REDUCE_OP,
>     +                                  operands, CONST0_RTX (<VEL>mode));
>         DONE;
>       })
> 
>     @@ -2166,7 +2173,8 @@
>          (match_operand:VI 1 "register_operand")]
>         "TARGET_VECTOR"
>       {
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_XOR, operands,
>     CONST0_RTX (<VEL>mode));
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_XOR,
>     riscv_vector::REDUCE_OP,
>     +                                  operands, CONST0_RTX (<VEL>mode));
>         DONE;
>       })
> 
>     @@ -2189,8 +2197,9 @@
>         "&& 1"
>         [(const_int 0)]
>       {
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_UNORDERED, operands,
>     -                                  CONST0_RTX (<VEL>mode));
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_UNORDERED,
>     +                                  riscv_vector::REDUCE_OP_FRM_DYN,
>     +                                  operands, CONST0_RTX (<VEL>mode));
>         DONE;
>       }
>       [(set_attr "type" "vector")])
>     @@ -2203,7 +2212,8 @@
>         REAL_VALUE_TYPE rv;
>         real_inf (&rv, true);
>         rtx f = const_double_from_real_value (rv, <VEL>mode);
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, operands, f);
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX,
>     riscv_vector::REDUCE_OP,
>     +                                  operands, f);
>         DONE;
>       })
> 
>     @@ -2215,7 +2225,8 @@
>         REAL_VALUE_TYPE rv;
>         real_inf (&rv, false);
>         rtx f = const_double_from_real_value (rv, <VEL>mode);
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, operands, f);
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN,
>     riscv_vector::REDUCE_OP,
>     +                                  operands, f);
>         DONE;
>       })
> 
>     @@ -2238,9 +2249,10 @@
>         "&& 1"
>         [(const_int 0)]
>       {
>     -  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED, operands,
>     -                                 operands[1],
>     -                               
>       riscv_vector::reduction_type::FOLD_LEFT);
>     +  rtx ops[] = {operands[0], operands[2]};
>     +  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED,
>     +                                  riscv_vector::REDUCE_OP_FRM_DYN,
>     +                                  ops, operands[1]);
>         DONE;
>       }
>       [(set_attr "type" "vector")])
>     @@ -2263,9 +2275,12 @@
>         if (rtx_equal_p (operands[4], const0_rtx))
>           emit_move_insn (operands[0], operands[1]);
>         else
>     -    riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED, operands,
>     -                                   operands[1],
>     -                                 
>       riscv_vector::reduction_type::MASK_LEN_FOLD_LEFT);
>     +    {
>     +      rtx ops[] = {operands[0], operands[2], operands[3], operands[4]};
>     +      riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED,
>     +                                     
>     riscv_vector::REDUCE_OP_M_FRM_DYN,
>     +                                      ops, operands[1]);
>     +    }
>         DONE;
>       }
>       [(set_attr "type" "vector")])
>     diff --git a/gcc/config/riscv/riscv-protos.h
>     b/gcc/config/riscv/riscv-protos.h
>     index 44fa36c32ab..bb94a7e0441 100644
>     --- a/gcc/config/riscv/riscv-protos.h
>     +++ b/gcc/config/riscv/riscv-protos.h
>     @@ -414,12 +414,6 @@ enum mask_policy
>       /* Return true if VALUE is agnostic or any policy.  */
>       #define IS_AGNOSTIC(VALUE) (bool) (VALUE & 0x1 || (VALUE >> 1 & 0x1))
> 
>     -enum class reduction_type
>     -{
>     -  UNORDERED,
>     -  FOLD_LEFT,
>     -  MASK_LEN_FOLD_LEFT,
>     -};
>       enum tail_policy get_prefer_tail_policy ();
>       enum mask_policy get_prefer_mask_policy ();
>       rtx get_avl_type_rtx (enum avl_type);
>     @@ -433,8 +427,7 @@ void expand_vec_cmp (rtx, rtx_code, rtx, rtx);
>       bool expand_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool);
>       void expand_cond_len_unop (unsigned, rtx *);
>       void expand_cond_len_binop (unsigned, rtx *);
>     -void expand_reduction (unsigned, rtx *, rtx,
>     -                      reduction_type = reduction_type::UNORDERED);
>     +void expand_reduction (unsigned, unsigned, rtx *, rtx);
>       #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 668594b65ed..7e9fd9ec741 100644
>     --- a/gcc/config/riscv/riscv-v.cc
>     +++ b/gcc/config/riscv/riscv-v.cc
>     @@ -67,6 +67,18 @@ const_vlmax_p (machine_mode mode)
>           : false;
>       }
> 
>     +/* Helper functions for insn_flags && insn_types */
>     +
>     +/* Return true if caller need pass mask operand for insn pattern with
>     +   INSN_FLAGS. */
>     +
>     +static bool
>     +need_mask_operand_p (unsigned insn_flags)
>     +{
>     +  return (insn_flags & HAS_MASK_P)
>     +        && !(insn_flags & (USE_ONE_TRUE_MASK_P |
>     USE_ALL_TRUES_MASK_P));
>     +}
>     +
>       template <int MAX_OPERANDS> class insn_expander
>       {
>       public:
>     @@ -3206,48 +3218,38 @@ expand_cond_len_ternop (unsigned icode, rtx
>     *ops)
>         expand_cond_len_op (icode, TERNARY_OP_P, cond_ops, len);
>       }
> 
>     -/* Expand reduction operations.  */
>     +/* Expand reduction operations.
>     +     Case 1: ops = {scalar_dest, vector_src}
>     +     Case 2: ops = {scalar_dest, vector_src, mask, vl}
>     +*/
>       void
>     -expand_reduction (unsigned unspec, rtx *ops, rtx init,
>     reduction_type type)
>     +expand_reduction (unsigned unspec, unsigned insn_flags, rtx *ops,
>     rtx init)
>       {
>     -  rtx vector = type == reduction_type::UNORDERED ? ops[1] : ops[2];
>     -  machine_mode vmode = GET_MODE (vector);
>     -  machine_mode vel_mode = GET_MODE (ops[0]);
>     +  rtx scalar_dest = ops[0];
>     +  rtx vector_src = ops[1];
>     +  machine_mode vmode = GET_MODE (vector_src);
>     +  machine_mode vel_mode = GET_MODE (scalar_dest);
>         machine_mode m1_mode = get_m1_mode (vel_mode).require ();
> 
>         rtx m1_tmp = gen_reg_rtx (m1_mode);
>         rtx scalar_move_ops[] = {m1_tmp, init};
>         emit_nonvlmax_insn (code_for_pred_broadcast (m1_mode),
>     SCALAR_MOVE_OP,
>     -                      scalar_move_ops,
>     -                      type == reduction_type::MASK_LEN_FOLD_LEFT
>     -                        ? ops[4]
>     -                        : CONST1_RTX (Pmode));
>     +                     scalar_move_ops,
>     +                     need_mask_operand_p (insn_flags) ? ops[3]
>     +                                                      : CONST1_RTX
>     (Pmode));
>         rtx m1_tmp2 = gen_reg_rtx (m1_mode);
>     -  rtx reduc_ops[] = {m1_tmp2, vector, m1_tmp};
>     +  rtx reduc_ops[] = {m1_tmp2, vector_src, m1_tmp};
>     +  insn_code icode = code_for_pred (unspec, vmode);
> 
>     -  if (unspec == UNSPEC_REDUC_SUM_ORDERED
>     -      || unspec == UNSPEC_WREDUC_SUM_ORDERED
>     -      || unspec == UNSPEC_REDUC_SUM_UNORDERED
>     -      || unspec == UNSPEC_WREDUC_SUM_UNORDERED)
>     +  if (need_mask_operand_p (insn_flags))
>           {
>     -      insn_code icode = code_for_pred (unspec, vmode);
>     -      if (type == reduction_type::MASK_LEN_FOLD_LEFT)
>     -       {
>     -         rtx mask = ops[3];
>     -         rtx mask_len_reduc_ops[] = {m1_tmp2, mask, vector, m1_tmp};
>     -         emit_nonvlmax_insn (icode, REDUCE_OP_M_FRM_DYN,
>     mask_len_reduc_ops,
>     -                              ops[4]);
>     -       }
>     -      else
>     -       emit_vlmax_insn (icode, REDUCE_OP_FRM_DYN, reduc_ops);
>     +      rtx mask_len_reduc_ops[] = {m1_tmp2, ops[2], vector_src, m1_tmp};
>     +      emit_nonvlmax_insn (icode, insn_flags, mask_len_reduc_ops,
>     ops[3]);
>           }
>         else
>     -    {
>     -      insn_code icode = code_for_pred (unspec, vmode);
>     -      emit_vlmax_insn (icode, REDUCE_OP, reduc_ops);
>     -    }
>     +    emit_vlmax_insn (icode, insn_flags, reduc_ops);
> 
>     -  emit_insn (gen_pred_extract_first (m1_mode, ops[0], m1_tmp2));
>     +  emit_insn (gen_pred_extract_first (m1_mode, scalar_dest, m1_tmp2));
>       }
> 
>       /* Prepare ops for ternary operations.
>     --
>     2.36.3
>
  

Patch

diff --git a/gcc/config/riscv/autovec-opt.md b/gcc/config/riscv/autovec-opt.md
index df516849527..b47bae16193 100644
--- a/gcc/config/riscv/autovec-opt.md
+++ b/gcc/config/riscv/autovec-opt.md
@@ -1208,7 +1208,8 @@ 
   "&& 1"
   [(const_int 0)]
 {
-  riscv_vector::expand_reduction (<WREDUC_UNSPEC>, operands,
+  riscv_vector::expand_reduction (<WREDUC_UNSPEC>, riscv_vector::REDUCE_OP,
+                                  operands,
                                   CONST0_RTX (<V_DOUBLE_EXTEND_VEL>mode));
   DONE;
 }
@@ -1226,7 +1227,9 @@ 
   "&& 1"
   [(const_int 0)]
 {
-  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_UNORDERED, operands,
+  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_UNORDERED,
+                                  riscv_vector::REDUCE_OP_FRM_DYN,
+                                  operands,
                                   CONST0_RTX (<V_DOUBLE_EXTEND_VEL>mode));
   DONE;
 }
@@ -1245,9 +1248,9 @@ 
   "&& 1"
   [(const_int 0)]
 {
-  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED, operands,
-				  operands[1],
-				  riscv_vector::reduction_type::FOLD_LEFT);
+  riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED,
+                                  riscv_vector::REDUCE_OP_FRM_DYN,
+                                  operands, operands[1]);
   DONE;
 }
 [(set_attr "type" "vector")])
@@ -1271,9 +1274,12 @@ 
   if (rtx_equal_p (operands[4], const0_rtx))
     emit_move_insn (operands[0], operands[1]);
   else
-    riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED, operands,
-				    operands[1],
-				    riscv_vector::reduction_type::MASK_LEN_FOLD_LEFT);
+    {
+      rtx ops[] = {operands[0], operands[2], operands[3], operands[4]};
+      riscv_vector::expand_reduction (UNSPEC_WREDUC_SUM_ORDERED,
+                                      riscv_vector::REDUCE_OP_M_FRM_DYN,
+                                      ops, operands[1]);
+    }
   DONE;
 }
 [(set_attr "type" "vector")])
diff --git a/gcc/config/riscv/autovec.md b/gcc/config/riscv/autovec.md
index 8537b9d41f6..c6175a3b1f6 100644
--- a/gcc/config/riscv/autovec.md
+++ b/gcc/config/riscv/autovec.md
@@ -2096,7 +2096,8 @@ 
   "&& 1"
   [(const_int 0)]
 {
-  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM, operands, CONST0_RTX (<VEL>mode));
+  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM, riscv_vector::REDUCE_OP,
+                                  operands, CONST0_RTX (<VEL>mode));
   DONE;
 }
 [(set_attr "type" "vector")])
@@ -2108,7 +2109,8 @@ 
 {
   int prec = GET_MODE_PRECISION (<VEL>mode);
   rtx min = immed_wide_int_const (wi::min_value (prec, SIGNED), <VEL>mode);
-  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, operands, min);
+  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, riscv_vector::REDUCE_OP,
+                                  operands, min);
   DONE;
 })

@@ -2117,7 +2119,8 @@ 
    (match_operand:VI 1 "register_operand")]
   "TARGET_VECTOR"
 {
-  riscv_vector::expand_reduction (UNSPEC_REDUC_MAXU, operands, CONST0_RTX (<VEL>mode));
+  riscv_vector::expand_reduction (UNSPEC_REDUC_MAXU, riscv_vector::REDUCE_OP,
+                                  operands, CONST0_RTX (<VEL>mode));
   DONE;
 })

@@ -2128,7 +2131,8 @@ 
 {
   int prec = GET_MODE_PRECISION (<VEL>mode);
   rtx max = immed_wide_int_const (wi::max_value (prec, SIGNED), <VEL>mode);
-  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, operands, max);
+  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, riscv_vector::REDUCE_OP,
+                                  operands, max);
   DONE;
 })

@@ -2139,7 +2143,8 @@ 
 {
   int prec = GET_MODE_PRECISION (<VEL>mode);
   rtx max = immed_wide_int_const (wi::max_value (prec, UNSIGNED), <VEL>mode);
-  riscv_vector::expand_reduction (UNSPEC_REDUC_MINU, operands, max);
+  riscv_vector::expand_reduction (UNSPEC_REDUC_MINU, riscv_vector::REDUCE_OP,
+                                  operands, max);
   DONE;
 })

@@ -2148,7 +2153,8 @@ 
    (match_operand:VI 1 "register_operand")]
   "TARGET_VECTOR"
 {
-  riscv_vector::expand_reduction (UNSPEC_REDUC_AND, operands, CONSTM1_RTX (<VEL>mode));
+  riscv_vector::expand_reduction (UNSPEC_REDUC_AND, riscv_vector::REDUCE_OP,
+                                  operands, CONSTM1_RTX (<VEL>mode));
   DONE;
 })

@@ -2157,7 +2163,8 @@ 
    (match_operand:VI 1 "register_operand")]
   "TARGET_VECTOR"
 {
-  riscv_vector::expand_reduction (UNSPEC_REDUC_OR, operands, CONST0_RTX (<VEL>mode));
+  riscv_vector::expand_reduction (UNSPEC_REDUC_OR, riscv_vector::REDUCE_OP,
+                                  operands, CONST0_RTX (<VEL>mode));
   DONE;
 })

@@ -2166,7 +2173,8 @@ 
    (match_operand:VI 1 "register_operand")]
   "TARGET_VECTOR"
 {
-  riscv_vector::expand_reduction (UNSPEC_REDUC_XOR, operands, CONST0_RTX (<VEL>mode));
+  riscv_vector::expand_reduction (UNSPEC_REDUC_XOR, riscv_vector::REDUCE_OP,
+                                  operands, CONST0_RTX (<VEL>mode));
   DONE;
 })

@@ -2189,8 +2197,9 @@ 
   "&& 1"
   [(const_int 0)]
 {
-  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_UNORDERED, operands,
-                                  CONST0_RTX (<VEL>mode));
+  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_UNORDERED,
+                                  riscv_vector::REDUCE_OP_FRM_DYN,
+                                  operands, CONST0_RTX (<VEL>mode));
   DONE;
 }
 [(set_attr "type" "vector")])
@@ -2203,7 +2212,8 @@ 
   REAL_VALUE_TYPE rv;
   real_inf (&rv, true);
   rtx f = const_double_from_real_value (rv, <VEL>mode);
-  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, operands, f);
+  riscv_vector::expand_reduction (UNSPEC_REDUC_MAX, riscv_vector::REDUCE_OP,
+                                  operands, f);
   DONE;
 })

@@ -2215,7 +2225,8 @@ 
   REAL_VALUE_TYPE rv;
   real_inf (&rv, false);
   rtx f = const_double_from_real_value (rv, <VEL>mode);
-  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, operands, f);
+  riscv_vector::expand_reduction (UNSPEC_REDUC_MIN, riscv_vector::REDUCE_OP,
+                                  operands, f);
   DONE;
 })

@@ -2238,9 +2249,10 @@ 
   "&& 1"
   [(const_int 0)]
 {
-  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED, operands,
-				  operands[1],
-				  riscv_vector::reduction_type::FOLD_LEFT);
+  rtx ops[] = {operands[0], operands[2]};
+  riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED,
+                                  riscv_vector::REDUCE_OP_FRM_DYN,
+                                  ops, operands[1]);
   DONE;
 }
 [(set_attr "type" "vector")])
@@ -2263,9 +2275,12 @@ 
   if (rtx_equal_p (operands[4], const0_rtx))
     emit_move_insn (operands[0], operands[1]);
   else
-    riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED, operands,
-				    operands[1],
-				    riscv_vector::reduction_type::MASK_LEN_FOLD_LEFT);
+    {
+      rtx ops[] = {operands[0], operands[2], operands[3], operands[4]};
+      riscv_vector::expand_reduction (UNSPEC_REDUC_SUM_ORDERED,
+                                      riscv_vector::REDUCE_OP_M_FRM_DYN,
+                                      ops, operands[1]);
+    }
   DONE;
 }
 [(set_attr "type" "vector")])
diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 44fa36c32ab..bb94a7e0441 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -414,12 +414,6 @@  enum mask_policy
 /* Return true if VALUE is agnostic or any policy.  */
 #define IS_AGNOSTIC(VALUE) (bool) (VALUE & 0x1 || (VALUE >> 1 & 0x1))

-enum class reduction_type
-{
-  UNORDERED,
-  FOLD_LEFT,
-  MASK_LEN_FOLD_LEFT,
-};
 enum tail_policy get_prefer_tail_policy ();
 enum mask_policy get_prefer_mask_policy ();
 rtx get_avl_type_rtx (enum avl_type);
@@ -433,8 +427,7 @@  void expand_vec_cmp (rtx, rtx_code, rtx, rtx);
 bool expand_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool);
 void expand_cond_len_unop (unsigned, rtx *);
 void expand_cond_len_binop (unsigned, rtx *);
-void expand_reduction (unsigned, rtx *, rtx,
-		       reduction_type = reduction_type::UNORDERED);
+void expand_reduction (unsigned, unsigned, rtx *, rtx);
 #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 668594b65ed..7e9fd9ec741 100644
--- a/gcc/config/riscv/riscv-v.cc
+++ b/gcc/config/riscv/riscv-v.cc
@@ -67,6 +67,18 @@  const_vlmax_p (machine_mode mode)
     : false;
 }

+/* Helper functions for insn_flags && insn_types */
+
+/* Return true if caller need pass mask operand for insn pattern with
+   INSN_FLAGS. */
+
+static bool
+need_mask_operand_p (unsigned insn_flags)
+{
+  return (insn_flags & HAS_MASK_P)
+	 && !(insn_flags & (USE_ONE_TRUE_MASK_P | USE_ALL_TRUES_MASK_P));
+}
+
 template <int MAX_OPERANDS> class insn_expander
 {
 public:
@@ -3206,48 +3218,38 @@  expand_cond_len_ternop (unsigned icode, rtx *ops)
   expand_cond_len_op (icode, TERNARY_OP_P, cond_ops, len);
 }

-/* Expand reduction operations.  */
+/* Expand reduction operations.
+     Case 1: ops = {scalar_dest, vector_src}
+     Case 2: ops = {scalar_dest, vector_src, mask, vl}
+*/
 void
-expand_reduction (unsigned unspec, rtx *ops, rtx init, reduction_type type)
+expand_reduction (unsigned unspec, unsigned insn_flags, rtx *ops, rtx init)
 {
-  rtx vector = type == reduction_type::UNORDERED ? ops[1] : ops[2];
-  machine_mode vmode = GET_MODE (vector);
-  machine_mode vel_mode = GET_MODE (ops[0]);
+  rtx scalar_dest = ops[0];
+  rtx vector_src = ops[1];
+  machine_mode vmode = GET_MODE (vector_src);
+  machine_mode vel_mode = GET_MODE (scalar_dest);
   machine_mode m1_mode = get_m1_mode (vel_mode).require ();

   rtx m1_tmp = gen_reg_rtx (m1_mode);
   rtx scalar_move_ops[] = {m1_tmp, init};
   emit_nonvlmax_insn (code_for_pred_broadcast (m1_mode), SCALAR_MOVE_OP,
-		       scalar_move_ops,
-		       type == reduction_type::MASK_LEN_FOLD_LEFT
-			 ? ops[4]
-			 : CONST1_RTX (Pmode));
+		      scalar_move_ops,
+		      need_mask_operand_p (insn_flags) ? ops[3]
+						       : CONST1_RTX (Pmode));
   rtx m1_tmp2 = gen_reg_rtx (m1_mode);
-  rtx reduc_ops[] = {m1_tmp2, vector, m1_tmp};
+  rtx reduc_ops[] = {m1_tmp2, vector_src, m1_tmp};
+  insn_code icode = code_for_pred (unspec, vmode);

-  if (unspec == UNSPEC_REDUC_SUM_ORDERED
-      || unspec == UNSPEC_WREDUC_SUM_ORDERED
-      || unspec == UNSPEC_REDUC_SUM_UNORDERED
-      || unspec == UNSPEC_WREDUC_SUM_UNORDERED)
+  if (need_mask_operand_p (insn_flags))
     {
-      insn_code icode = code_for_pred (unspec, vmode);
-      if (type == reduction_type::MASK_LEN_FOLD_LEFT)
-	{
-	  rtx mask = ops[3];
-	  rtx mask_len_reduc_ops[] = {m1_tmp2, mask, vector, m1_tmp};
-	  emit_nonvlmax_insn (icode, REDUCE_OP_M_FRM_DYN, mask_len_reduc_ops,
-			       ops[4]);
-	}
-      else
-	emit_vlmax_insn (icode, REDUCE_OP_FRM_DYN, reduc_ops);
+      rtx mask_len_reduc_ops[] = {m1_tmp2, ops[2], vector_src, m1_tmp};
+      emit_nonvlmax_insn (icode, insn_flags, mask_len_reduc_ops, ops[3]);
     }
   else
-    {
-      insn_code icode = code_for_pred (unspec, vmode);
-      emit_vlmax_insn (icode, REDUCE_OP, reduc_ops);
-    }
+    emit_vlmax_insn (icode, insn_flags, reduc_ops);

-  emit_insn (gen_pred_extract_first (m1_mode, ops[0], m1_tmp2));
+  emit_insn (gen_pred_extract_first (m1_mode, scalar_dest, m1_tmp2));
 }

 /* Prepare ops for ternary operations.