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.
