}
};
+/* Implements reduction instructions. */
+template<rtx_code CODE>
+class reducop : public function_base
+{
+public:
+ bool apply_mask_policy_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (
+ code_for_pred_reduc (CODE, e.vector_mode (), e.vector_mode ()));
+ }
+};
+
+/* Implements widen reduction instructions. */
+template<int UNSPEC>
+class widen_reducop : public function_base
+{
+public:
+ bool apply_mask_policy_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred_widen_reduc_plus (UNSPEC,
+ e.vector_mode (),
+ e.vector_mode ()));
+ }
+};
+
+/* Implements floating-point reduction instructions. */
+template<int UNSPEC>
+class freducop : public function_base
+{
+public:
+ bool apply_mask_policy_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (
+ code_for_pred_reduc_plus (UNSPEC, e.vector_mode (), e.vector_mode ()));
+ }
+};
+
+/* Implements widening floating-point reduction instructions. */
+template<int UNSPEC>
+class widen_freducop : public function_base
+{
+public:
+ bool apply_mask_policy_p () const override { return false; }
+
+ rtx expand (function_expander &e) const override
+ {
+ return e.use_exact_insn (code_for_pred_widen_reduc_plus (UNSPEC,
+ e.vector_mode (),
+ e.vector_mode ()));
+ }
+};
+
static CONSTEXPR const vsetvl<false> vsetvl_obj;
static CONSTEXPR const vsetvl<true> vsetvlmax_obj;
static CONSTEXPR const loadstore<false, LST_UNIT_STRIDE, false> vle_obj;
static CONSTEXPR const vfncvt_rtz_x<UNSIGNED_FIX> vfncvt_rtz_xu_obj;
static CONSTEXPR const vfncvt_f vfncvt_f_obj;
static CONSTEXPR const vfncvt_rod_f vfncvt_rod_f_obj;
+static CONSTEXPR const reducop<PLUS> vredsum_obj;
+static CONSTEXPR const reducop<UMAX> vredmaxu_obj;
+static CONSTEXPR const reducop<SMAX> vredmax_obj;
+static CONSTEXPR const reducop<UMIN> vredminu_obj;
+static CONSTEXPR const reducop<SMIN> vredmin_obj;
+static CONSTEXPR const reducop<AND> vredand_obj;
+static CONSTEXPR const reducop<IOR> vredor_obj;
+static CONSTEXPR const reducop<XOR> vredxor_obj;
+static CONSTEXPR const widen_reducop<UNSPEC_WREDUC_SUM> vwredsum_obj;
+static CONSTEXPR const widen_reducop<UNSPEC_WREDUC_USUM> vwredsumu_obj;
+static CONSTEXPR const freducop<UNSPEC_UNORDERED> vfredusum_obj;
+static CONSTEXPR const freducop<UNSPEC_ORDERED> vfredosum_obj;
+static CONSTEXPR const reducop<SMAX> vfredmax_obj;
+static CONSTEXPR const reducop<SMIN> vfredmin_obj;
+static CONSTEXPR const widen_freducop<UNSPEC_UNORDERED> vfwredusum_obj;
+static CONSTEXPR const widen_freducop<UNSPEC_ORDERED> vfwredosum_obj;
/* Declare the function base NAME, pointing it to an instance
of class <NAME>_obj. */
BASE (vfncvt_rtz_xu)
BASE (vfncvt_f)
BASE (vfncvt_rod_f)
+BASE (vredsum)
+BASE (vredmaxu)
+BASE (vredmax)
+BASE (vredminu)
+BASE (vredmin)
+BASE (vredand)
+BASE (vredor)
+BASE (vredxor)
+BASE (vwredsum)
+BASE (vwredsumu)
+BASE (vfredusum)
+BASE (vfredosum)
+BASE (vfredmax)
+BASE (vfredmin)
+BASE (vfwredosum)
+BASE (vfwredusum)
} // end namespace riscv_vector
extern const function_base *const vfncvt_rtz_xu;
extern const function_base *const vfncvt_f;
extern const function_base *const vfncvt_rod_f;
+extern const function_base *const vredsum;
+extern const function_base *const vredmaxu;
+extern const function_base *const vredmax;
+extern const function_base *const vredminu;
+extern const function_base *const vredmin;
+extern const function_base *const vredand;
+extern const function_base *const vredor;
+extern const function_base *const vredxor;
+extern const function_base *const vwredsum;
+extern const function_base *const vwredsumu;
+extern const function_base *const vfredusum;
+extern const function_base *const vfredosum;
+extern const function_base *const vfredmax;
+extern const function_base *const vfredmin;
+extern const function_base *const vfwredosum;
+extern const function_base *const vfwredusum;
}
} // end namespace riscv_vector
DEF_RVV_FUNCTION (vfncvt_f, narrow_alu, full_preds, f_to_nf_f_w_ops)
DEF_RVV_FUNCTION (vfncvt_rod_f, narrow_alu, full_preds, f_to_nf_f_w_ops)
-/* TODO: 14. Vector Reduction Operations. */
+/* 14. Vector Reduction Operations. */
+
+// 14.1. Vector Single-Width Integer Reduction Instructions
+DEF_RVV_FUNCTION (vredsum, reduc_alu, no_mu_preds, iu_vs_ops)
+DEF_RVV_FUNCTION (vredmaxu, reduc_alu, no_mu_preds, iu_vs_ops)
+DEF_RVV_FUNCTION (vredmax, reduc_alu, no_mu_preds, iu_vs_ops)
+DEF_RVV_FUNCTION (vredminu, reduc_alu, no_mu_preds, iu_vs_ops)
+DEF_RVV_FUNCTION (vredmin, reduc_alu, no_mu_preds, iu_vs_ops)
+DEF_RVV_FUNCTION (vredand, reduc_alu, no_mu_preds, iu_vs_ops)
+DEF_RVV_FUNCTION (vredor, reduc_alu, no_mu_preds, iu_vs_ops)
+DEF_RVV_FUNCTION (vredxor, reduc_alu, no_mu_preds, iu_vs_ops)
+
+// 14.2. Vector Widening Integer Reduction Instructions
+DEF_RVV_FUNCTION (vwredsum, reduc_alu, no_mu_preds, wi_vs_ops)
+DEF_RVV_FUNCTION (vwredsumu, reduc_alu, no_mu_preds, wu_vs_ops)
+
+// 14.3. Vector Single-Width Floating-Point Reduction Instructions
+DEF_RVV_FUNCTION (vfredusum, reduc_alu, no_mu_preds, f_vs_ops)
+DEF_RVV_FUNCTION (vfredosum, reduc_alu, no_mu_preds, f_vs_ops)
+DEF_RVV_FUNCTION (vfredmax, reduc_alu, no_mu_preds, f_vs_ops)
+DEF_RVV_FUNCTION (vfredmin, reduc_alu, no_mu_preds, f_vs_ops)
+
+// 14.4. Vector Widening Floating-Point Reduction Instructions
+DEF_RVV_FUNCTION (vfwredosum, reduc_alu, no_mu_preds, wf_vs_ops)
+DEF_RVV_FUNCTION (vfwredusum, reduc_alu, no_mu_preds, wf_vs_ops)
/* 15. Vector Mask Instructions. */
}
};
+/* reduc_alu_def class. */
+struct reduc_alu_def : public build_base
+{
+ char *get_name (function_builder &b, const function_instance &instance,
+ bool overloaded_p) const override
+ {
+ b.append_base_name (instance.base_name);
+
+ /* vop_<op> --> vop<sew>_<op>_<type>. */
+ if (!overloaded_p)
+ {
+ b.append_name (operand_suffixes[instance.op_info->op]);
+ b.append_name (type_suffixes[instance.type.index].vector);
+ vector_type_index ret_type_idx
+ = instance.op_info->ret.get_base_vector_type (
+ builtin_types[instance.type.index].vector);
+ b.append_name (type_suffixes[ret_type_idx].vector);
+ }
+
+ /* According to rvv-intrinsic-doc, it does not add "_m" suffix
+ for vop_m C++ overloaded API. */
+ if (overloaded_p && instance.pred == PRED_TYPE_m)
+ return b.finish_name ();
+ b.append_name (predication_suffixes[instance.pred]);
+ return b.finish_name ();
+ }
+};
+
SHAPE(vsetvl, vsetvl)
SHAPE(vsetvl, vsetvlmax)
SHAPE(loadstore, loadstore)
SHAPE(narrow_alu, narrow_alu)
SHAPE(move, move)
SHAPE(mask_alu, mask_alu)
+SHAPE(reduc_alu, reduc_alu)
} // end namespace riscv_vector
extern const function_shape *const narrow_alu;
extern const function_shape *const move;
extern const function_shape *const mask_alu;
+extern const function_shape *const reduc_alu;
}
} // end namespace riscv_vector
#define DEF_RVV_WCONVERT_F_OPS(TYPE, REQUIRE)
#endif
+/* Use "DEF_RVV_WI_OPS" macro include all signed integer can be widened which
+ will be iterated and registered as intrinsic functions. */
+#ifndef DEF_RVV_WI_OPS
+#define DEF_RVV_WI_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_WU_OPS" macro include all unsigned integer can be widened which
+ will be iterated and registered as intrinsic functions. */
+#ifndef DEF_RVV_WU_OPS
+#define DEF_RVV_WU_OPS(TYPE, REQUIRE)
+#endif
+
+/* Use "DEF_RVV_WF_OPS" macro include all floating-point can be widened which
+ will be iterated and registered as intrinsic functions. */
+#ifndef DEF_RVV_WF_OPS
+#define DEF_RVV_WF_OPS(TYPE, REQUIRE)
+#endif
+
DEF_RVV_I_OPS (vint8mf8_t, RVV_REQUIRE_ZVE64)
DEF_RVV_I_OPS (vint8mf4_t, 0)
DEF_RVV_I_OPS (vint8mf2_t, 0)
DEF_RVV_WCONVERT_F_OPS (vfloat64m4_t, RVV_REQUIRE_ELEN_FP_64)
DEF_RVV_WCONVERT_F_OPS (vfloat64m8_t, RVV_REQUIRE_ELEN_FP_64)
+DEF_RVV_WI_OPS (vint8mf8_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WI_OPS (vint8mf4_t, 0)
+DEF_RVV_WI_OPS (vint8mf2_t, 0)
+DEF_RVV_WI_OPS (vint8m1_t, 0)
+DEF_RVV_WI_OPS (vint8m2_t, 0)
+DEF_RVV_WI_OPS (vint8m4_t, 0)
+DEF_RVV_WI_OPS (vint8m8_t, 0)
+DEF_RVV_WI_OPS (vint16mf4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WI_OPS (vint16mf2_t, 0)
+DEF_RVV_WI_OPS (vint16m1_t, 0)
+DEF_RVV_WI_OPS (vint16m2_t, 0)
+DEF_RVV_WI_OPS (vint16m4_t, 0)
+DEF_RVV_WI_OPS (vint16m8_t, 0)
+DEF_RVV_WI_OPS (vint32mf2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WI_OPS (vint32m1_t, 0)
+DEF_RVV_WI_OPS (vint32m2_t, 0)
+DEF_RVV_WI_OPS (vint32m4_t, 0)
+DEF_RVV_WI_OPS (vint32m8_t, 0)
+
+DEF_RVV_WU_OPS (vuint8mf8_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WU_OPS (vuint8mf4_t, 0)
+DEF_RVV_WU_OPS (vuint8mf2_t, 0)
+DEF_RVV_WU_OPS (vuint8m1_t, 0)
+DEF_RVV_WU_OPS (vuint8m2_t, 0)
+DEF_RVV_WU_OPS (vuint8m4_t, 0)
+DEF_RVV_WU_OPS (vuint8m8_t, 0)
+DEF_RVV_WU_OPS (vuint16mf4_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WU_OPS (vuint16mf2_t, 0)
+DEF_RVV_WU_OPS (vuint16m1_t, 0)
+DEF_RVV_WU_OPS (vuint16m2_t, 0)
+DEF_RVV_WU_OPS (vuint16m4_t, 0)
+DEF_RVV_WU_OPS (vuint16m8_t, 0)
+DEF_RVV_WU_OPS (vuint32mf2_t, RVV_REQUIRE_ZVE64)
+DEF_RVV_WU_OPS (vuint32m1_t, 0)
+DEF_RVV_WU_OPS (vuint32m2_t, 0)
+DEF_RVV_WU_OPS (vuint32m4_t, 0)
+DEF_RVV_WU_OPS (vuint32m8_t, 0)
+
+DEF_RVV_WF_OPS (vfloat32mf2_t, RVV_REQUIRE_ELEN_FP_32 | RVV_REQUIRE_ZVE64)
+DEF_RVV_WF_OPS (vfloat32m1_t, RVV_REQUIRE_ELEN_FP_32)
+DEF_RVV_WF_OPS (vfloat32m2_t, RVV_REQUIRE_ELEN_FP_32)
+DEF_RVV_WF_OPS (vfloat32m4_t, RVV_REQUIRE_ELEN_FP_32)
+DEF_RVV_WF_OPS (vfloat32m8_t, RVV_REQUIRE_ELEN_FP_32)
+
#undef DEF_RVV_I_OPS
#undef DEF_RVV_U_OPS
#undef DEF_RVV_F_OPS
#undef DEF_RVV_WCONVERT_I_OPS
#undef DEF_RVV_WCONVERT_U_OPS
#undef DEF_RVV_WCONVERT_F_OPS
+#undef DEF_RVV_WI_OPS
+#undef DEF_RVV_WU_OPS
+#undef DEF_RVV_WF_OPS
#include "riscv-vector-builtins-types.def"
{NUM_VECTOR_TYPES, 0}};
+/* A list of all signed integer can be widened will be registered for intrinsic
+ * functions. */
+static const rvv_type_info wi_ops[] = {
+#define DEF_RVV_WI_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+ {NUM_VECTOR_TYPES, 0}};
+
+/* A list of all unsigned integer can be widened will be registered for
+ * intrinsic functions. */
+static const rvv_type_info wu_ops[] = {
+#define DEF_RVV_WU_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+ {NUM_VECTOR_TYPES, 0}};
+
+/* A list of all floating-point can be widened will be registered for intrinsic
+ * functions. */
+static const rvv_type_info wf_ops[] = {
+#define DEF_RVV_WF_OPS(TYPE, REQUIRE) {VECTOR_TYPE_##TYPE, REQUIRE},
+#include "riscv-vector-builtins-types.def"
+ {NUM_VECTOR_TYPES, 0}};
+
/* A list of all signed integer that SEW = 64 require full 'V' extension will be
registered for intrinsic functions. */
static const rvv_type_info full_v_i_ops[] = {
static CONSTEXPR const rvv_arg_type_info v_args[]
= {rvv_arg_type_info (RVV_BASE_vector), rvv_arg_type_info_end};
+/* A list of args for vector_type func (vector_type, lmul1_type) function. */
+static CONSTEXPR const rvv_arg_type_info vs_args[]
+ = {rvv_arg_type_info (RVV_BASE_vector),
+ rvv_arg_type_info (RVV_BASE_lmul1_vector), rvv_arg_type_info_end};
+
+/* A list of args for vector_type func (vector_type, widen_lmul1_type) function.
+ */
+static CONSTEXPR const rvv_arg_type_info wvs_args[]
+ = {rvv_arg_type_info (RVV_BASE_vector),
+ rvv_arg_type_info (RVV_BASE_widen_lmul1_vector), rvv_arg_type_info_end};
+
/* A list of args for vector_type func (vector_type) function. */
static CONSTEXPR const rvv_arg_type_info f_v_args[]
= {rvv_arg_type_info (RVV_BASE_float_vector), rvv_arg_type_info_end};
= {PRED_TYPE_none, PRED_TYPE_m, PRED_TYPE_tu, PRED_TYPE_tum,
PRED_TYPE_tumu, PRED_TYPE_mu, NUM_PRED_TYPES};
+/* vop/vop_m/vop_tu/vop_tum/ will be registered. */
+static CONSTEXPR const predication_type_index no_mu_preds[]
+ = {PRED_TYPE_none, PRED_TYPE_m, PRED_TYPE_tu, PRED_TYPE_tum, NUM_PRED_TYPES};
+
/* vop/vop_tu will be registered. */
static CONSTEXPR const predication_type_index none_tu_preds[]
= {PRED_TYPE_none, PRED_TYPE_tu, NUM_PRED_TYPES};
rvv_arg_type_info (RVV_BASE_vector), /* Return type */
v_args /* Args */};
+/* A static operand information for vector_type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info iu_vs_ops
+ = {iu_ops, /* Types */
+ OP_TYPE_vs, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_lmul1_vector), /* Return type */
+ vs_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info f_vs_ops
+ = {f_ops, /* Types */
+ OP_TYPE_vs, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_lmul1_vector), /* Return type */
+ vs_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info wi_vs_ops
+ = {wi_ops, /* Types */
+ OP_TYPE_vs, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_widen_lmul1_vector), /* Return type */
+ wvs_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info wu_vs_ops
+ = {wu_ops, /* Types */
+ OP_TYPE_vs, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_widen_lmul1_vector), /* Return type */
+ wvs_args /* Args */};
+
+/* A static operand information for vector_type func (vector_type)
+ * function registration. */
+static CONSTEXPR const rvv_op_info wf_vs_ops
+ = {wf_ops, /* Types */
+ OP_TYPE_vs, /* Suffix */
+ rvv_arg_type_info (RVV_BASE_widen_lmul1_vector), /* Return type */
+ wvs_args /* Args */};
+
/* A static operand information for vector_type func (vector_type)
* function registration. */
static CONSTEXPR const rvv_op_info f_v_ops
|| type == RVV_BASE_uint32_index || type == RVV_BASE_uint64_index
|| type == RVV_BASE_float_vector
|| type == RVV_BASE_double_trunc_float_vector
- || type == RVV_BASE_double_trunc_vector;
+ || type == RVV_BASE_double_trunc_vector
+ || type == RVV_BASE_widen_lmul1_vector;
}
/* Check whether all the RVV_REQUIRE_* values in REQUIRED_EXTENSIONS are
poly_int64 nunits = GET_MODE_NUNITS (TYPE_MODE (type));
machine_mode inner_mode = GET_MODE_INNER (TYPE_MODE (type));
poly_int64 bitsize = GET_MODE_BITSIZE (inner_mode);
+ poly_int64 bytesize = GET_MODE_SIZE (inner_mode);
bool unsigned_p = TYPE_UNSIGNED (type);
if (unsigned_base_type_p (base_type))
case RVV_BASE_unsigned_vector:
inner_mode = int_mode_for_mode (inner_mode).require ();
break;
+ case RVV_BASE_lmul1_vector:
+ nunits = exact_div (BYTES_PER_RISCV_VECTOR, bytesize);
+ break;
+ case RVV_BASE_widen_lmul1_vector:
+ inner_mode
+ = get_mode_for_bitsize (bitsize * 2, FLOAT_MODE_P (inner_mode));
+ if (BYTES_PER_RISCV_VECTOR.coeffs[0] < (bytesize * 2).coeffs[0])
+ return NUM_VECTOR_TYPES;
+ nunits = exact_div (BYTES_PER_RISCV_VECTOR, bytesize * 2);
+ break;
default:
return NUM_VECTOR_TYPES;
}
case RVV_BASE_double_trunc_float_vector:
case RVV_BASE_signed_vector:
case RVV_BASE_unsigned_vector:
+ case RVV_BASE_lmul1_vector:
+ case RVV_BASE_widen_lmul1_vector:
if (get_base_vector_type (builtin_types[type_idx].vector)
!= NUM_VECTOR_TYPES)
return builtin_types[get_base_vector_type (
RVV_BASE_double_trunc_signed_vector,
RVV_BASE_double_trunc_unsigned_vector,
RVV_BASE_double_trunc_unsigned_scalar,
- RVV_BASE_float_vector,
RVV_BASE_double_trunc_float_vector,
+ RVV_BASE_float_vector,
+ RVV_BASE_lmul1_vector,
+ RVV_BASE_widen_lmul1_vector,
NUM_BASE_TYPES
};
;; 14. Vector reduction operations
;; vired vector single-width integer reduction instructions
;; viwred vector widening integer reduction instructions
-;; vfred vector single-width floating-point un-ordered reduction instruction
+;; vfredu vector single-width floating-point un-ordered reduction instruction
;; vfredo vector single-width floating-point ordered reduction instruction
-;; vfwred vector widening floating-point un-ordered reduction instruction
+;; vfwredu vector widening floating-point un-ordered reduction instruction
;; vfwredo vector widening floating-point ordered reduction instruction
;; 15. Vector mask instructions
;; vmalu vector mask-register logical instructions
vfcmp,vfminmax,vfsgnj,vfclass,vfmerge,vfmov,
vfcvtitof,vfcvtftoi,vfwcvtitof,vfwcvtftoi,
vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,
- vired,viwred,vfred,vfredo,vfwred,vfwredo,
+ vired,viwred,vfredu,vfredo,vfwredu,vfwredo,
vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovvx,vimovxv,vfmovvf,vfmovfv,
vislide,vislide1,vfslide1,vgather,vcompress,vmov"
(cond [(eq_attr "got" "load") (const_string "load")
UNSPEC_VFCVT
UNSPEC_UNSIGNED_VFCVT
UNSPEC_ROD
+
+ UNSPEC_REDUC
+ UNSPEC_WREDUC_SUM
+ UNSPEC_WREDUC_USUM
])
(define_mode_iterator V [
(VNx4DI "TARGET_MIN_VLEN > 32") (VNx8DI "TARGET_MIN_VLEN > 32")
])
+(define_mode_iterator VI_ZVE32 [
+ VNx1QI VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI
+ VNx1HI VNx2HI VNx4HI VNx8HI VNx16HI
+ VNx1SI VNx2SI VNx4SI VNx8SI
+])
+
+(define_mode_iterator VWI [
+ VNx1QI VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32")
+ VNx1HI VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32")
+ VNx1SI VNx2SI VNx4SI VNx8SI (VNx16SI "TARGET_MIN_VLEN > 32")
+])
+
+(define_mode_iterator VWI_ZVE32 [
+ VNx1QI VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI
+ VNx1HI VNx2HI VNx4HI VNx8HI VNx16HI
+])
+
(define_mode_iterator VF [
(VNx1SF "TARGET_VECTOR_ELEN_FP_32")
(VNx2SF "TARGET_VECTOR_ELEN_FP_32")
(VNx8DF "TARGET_VECTOR_ELEN_FP_64")
])
+(define_mode_iterator VF_ZVE32 [
+ (VNx1SF "TARGET_VECTOR_ELEN_FP_32")
+ (VNx2SF "TARGET_VECTOR_ELEN_FP_32")
+ (VNx4SF "TARGET_VECTOR_ELEN_FP_32")
+ (VNx8SF "TARGET_VECTOR_ELEN_FP_32")
+])
+
+(define_mode_iterator VWF [
+ VNx1SF VNx2SF VNx4SF VNx8SF (VNx16SF "TARGET_MIN_VLEN > 32")
+])
+
(define_mode_iterator VFULLI [
VNx1QI VNx2QI VNx4QI VNx8QI VNx16QI VNx32QI (VNx64QI "TARGET_MIN_VLEN > 32")
VNx1HI VNx2HI VNx4HI VNx8HI VNx16HI (VNx32HI "TARGET_MIN_VLEN > 32")
(VNx1DF "VNx1SI") (VNx2DF "VNx2SI") (VNx4DF "VNx4SI") (VNx8DF "VNx8SI")
])
+(define_mode_attr VLMUL1 [
+ (VNx1QI "VNx8QI") (VNx2QI "VNx8QI") (VNx4QI "VNx8QI")
+ (VNx8QI "VNx8QI") (VNx16QI "VNx8QI") (VNx32QI "VNx8QI") (VNx64QI "VNx8QI")
+ (VNx1HI "VNx4HI") (VNx2HI "VNx4HI") (VNx4HI "VNx4HI")
+ (VNx8HI "VNx4HI") (VNx16HI "VNx4HI") (VNx32HI "VNx4HI")
+ (VNx1SI "VNx2SI") (VNx2SI "VNx2SI") (VNx4SI "VNx2SI")
+ (VNx8SI "VNx2SI") (VNx16SI "VNx2SI")
+ (VNx1DI "VNx1DI") (VNx2DI "VNx1DI")
+ (VNx4DI "VNx1DI") (VNx8DI "VNx1DI")
+ (VNx1SF "VNx2SF") (VNx2SF "VNx2SF")
+ (VNx4SF "VNx2SF") (VNx8SF "VNx2SF") (VNx16SF "VNx2SF")
+ (VNx1DF "VNx1DF") (VNx2DF "VNx1DF")
+ (VNx4DF "VNx1DF") (VNx8DF "VNx1DF")
+])
+
+(define_mode_attr VLMUL1_ZVE32 [
+ (VNx1QI "VNx4QI") (VNx2QI "VNx4QI") (VNx4QI "VNx4QI")
+ (VNx8QI "VNx4QI") (VNx16QI "VNx4QI") (VNx32QI "VNx4QI")
+ (VNx1HI "VNx2HI") (VNx2HI "VNx2HI") (VNx4HI "VNx2HI")
+ (VNx8HI "VNx2HI") (VNx16HI "VNx2HI")
+ (VNx1SI "VNx1SI") (VNx2SI "VNx1SI") (VNx4SI "VNx1SI")
+ (VNx8SI "VNx1SI")
+ (VNx1SF "VNx2SF") (VNx2SF "VNx2SF")
+ (VNx4SF "VNx2SF") (VNx8SF "VNx2SF")
+])
+
+(define_mode_attr VWLMUL1 [
+ (VNx1QI "VNx4HI") (VNx2QI "VNx4HI") (VNx4QI "VNx4HI")
+ (VNx8QI "VNx4HI") (VNx16QI "VNx4HI") (VNx32QI "VNx4HI") (VNx64QI "VNx4HI")
+ (VNx1HI "VNx2SI") (VNx2HI "VNx2SI") (VNx4HI "VNx2SI")
+ (VNx8HI "VNx2SI") (VNx16HI "VNx2SI") (VNx32HI "VNx2SI")
+ (VNx1SI "VNx1DI") (VNx2SI "VNx1DI") (VNx4SI "VNx1DI")
+ (VNx8SI "VNx1DI") (VNx16SI "VNx1DI")
+ (VNx1SF "VNx1DF") (VNx2SF "VNx1DF")
+ (VNx4SF "VNx1DF") (VNx8SF "VNx1DF") (VNx16SF "VNx1DF")
+])
+
+(define_mode_attr VWLMUL1_ZVE32 [
+ (VNx1QI "VNx2HI") (VNx2QI "VNx2HI") (VNx4QI "VNx2HI")
+ (VNx8QI "VNx2HI") (VNx16QI "VNx2HI") (VNx32QI "VNx2HI")
+ (VNx1HI "VNx1SI") (VNx2HI "VNx1SI") (VNx4HI "VNx1SI")
+ (VNx8HI "VNx1SI") (VNx16HI "VNx1SI")
+])
+
+(define_mode_attr vlmul1 [
+ (VNx1QI "vnx8qi") (VNx2QI "vnx8qi") (VNx4QI "vnx8qi")
+ (VNx8QI "vnx8qi") (VNx16QI "vnx8qi") (VNx32QI "vnx8qi") (VNx64QI "vnx8qi")
+ (VNx1HI "vnx4hi") (VNx2HI "vnx4hi") (VNx4HI "vnx4hi")
+ (VNx8HI "vnx4hi") (VNx16HI "vnx4hi") (VNx32HI "vnx4hi")
+ (VNx1SI "vnx2si") (VNx2SI "vnx2si") (VNx4SI "vnx2si")
+ (VNx8SI "vnx2si") (VNx16SI "vnx2si")
+ (VNx1DI "vnx1DI") (VNx2DI "vnx1DI")
+ (VNx4DI "vnx1DI") (VNx8DI "vnx1DI")
+ (VNx1SF "vnx2sf") (VNx2SF "vnx2sf")
+ (VNx4SF "vnx2sf") (VNx8SF "vnx2sf") (VNx16SF "vnx2sf")
+ (VNx1DF "vnx1df") (VNx2DF "vnx1df")
+ (VNx4DF "vnx1df") (VNx8DF "vnx1df")
+])
+
+(define_mode_attr vlmul1_zve32 [
+ (VNx1QI "vnx4qi") (VNx2QI "vnx4qi") (VNx4QI "vnx4qi")
+ (VNx8QI "vnx4qi") (VNx16QI "vnx4qi") (VNx32QI "vnx4qi")
+ (VNx1HI "vnx2hi") (VNx2HI "vnx2hi") (VNx4HI "vnx2hi")
+ (VNx8HI "vnx2hi") (VNx16HI "vnx2hi")
+ (VNx1SI "vnx1si") (VNx2SI "vnx1si") (VNx4SI "vnx1si")
+ (VNx8SI "vnx1si")
+ (VNx1SF "vnx1sf") (VNx2SF "vnx1sf")
+ (VNx4SF "vnx1sf") (VNx8SF "vnx1sf")
+])
+
+(define_mode_attr vwlmul1 [
+ (VNx1QI "vnx4hi") (VNx2QI "vnx4hi") (VNx4QI "vnx4hi")
+ (VNx8QI "vnx4hi") (VNx16QI "vnx4hi") (VNx32QI "vnx4hi") (VNx64QI "vnx4hi")
+ (VNx1HI "vnx2si") (VNx2HI "vnx2si") (VNx4HI "vnx2si")
+ (VNx8HI "vnx2si") (VNx16HI "vnx2si") (VNx32HI "vnx2SI")
+ (VNx1SI "vnx2di") (VNx2SI "vnx2di") (VNx4SI "vnx2di")
+ (VNx8SI "vnx2di") (VNx16SI "vnx2di")
+ (VNx1SF "vnx1df") (VNx2SF "vnx1df")
+ (VNx4SF "vnx1df") (VNx8SF "vnx1df") (VNx16SF "vnx1df")
+])
+
+(define_mode_attr vwlmul1_zve32 [
+ (VNx1QI "vnx2hi") (VNx2QI "vnx2hi") (VNx4QI "vnx2hi")
+ (VNx8QI "vnx2hi") (VNx16QI "vnx2hi") (VNx32QI "vnx2hi")
+ (VNx1HI "vnx1si") (VNx2HI "vnx1si") (VNx4HI "vnx1si")
+ (VNx8HI "vnx1si") (VNx16HI "vnx1SI")
+])
+
+(define_int_iterator WREDUC [UNSPEC_WREDUC_SUM UNSPEC_WREDUC_USUM])
+
(define_int_iterator ORDER [UNSPEC_ORDERED UNSPEC_UNORDERED])
(define_int_iterator VMULH [UNSPEC_VMULHS UNSPEC_VMULHU UNSPEC_VMULHSU])
(define_int_attr v_su [(UNSPEC_VMULHS "") (UNSPEC_VMULHU "u") (UNSPEC_VMULHSU "su")
(UNSPEC_VNCLIP "") (UNSPEC_VNCLIPU "u")
- (UNSPEC_VFCVT "") (UNSPEC_UNSIGNED_VFCVT "u")])
+ (UNSPEC_VFCVT "") (UNSPEC_UNSIGNED_VFCVT "u")
+ (UNSPEC_WREDUC_SUM "") (UNSPEC_WREDUC_USUM "u")])
(define_int_attr sat_op [(UNSPEC_VAADDU "aaddu") (UNSPEC_VAADD "aadd")
(UNSPEC_VASUBU "asubu") (UNSPEC_VASUB "asub")
(UNSPEC_VSMUL "smul") (UNSPEC_VSSRL "ssrl")
(define_code_iterator any_fix [fix unsigned_fix])
(define_code_iterator any_float [float unsigned_float])
+(define_code_iterator any_reduc [plus umax smax umin smin and ior xor])
+(define_code_iterator any_freduc [smax smin])
+(define_code_attr reduc [(plus "sum") (umax "maxu") (smax "max") (umin "minu")
+ (smin "min") (and "and") (ior "or") (xor "xor")])
+
(define_code_attr fix_cvt [(fix "fix_trunc") (unsigned_fix "fixuns_trunc")])
(define_code_attr float_cvt [(float "float") (unsigned_float "floatuns")])
vfcmp,vfminmax,vfsgnj,vfclass,vfmerge,vfmov,\
vfcvtitof,vfcvtftoi,vfwcvtitof,vfwcvtftoi,\
vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,\
- vired,viwred,vfred,vfredo,vfwred,vfwredo,\
+ vired,viwred,vfredu,vfredo,vfwredu,vfwredo,\
vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovvx,vimovxv,vfmovvf,vfmovfv,\
vislide,vislide1,vfslide1,vgather,vcompress")
(const_string "true")]
vfcmp,vfminmax,vfsgnj,vfclass,vfmerge,vfmov,\
vfcvtitof,vfcvtftoi,vfwcvtitof,vfwcvtftoi,\
vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,\
- vired,viwred,vfred,vfredo,vfwred,vfwredo,\
+ vired,viwred,vfredu,vfredo,vfwredu,vfwredo,\
vmalu,vmpop,vmffs,vmsfs,vmiota,vmidx,vimovxv,vfmovfv,\
vislide,vislide1,vfslide1,vgather,vcompress")
(const_string "true")]
vfwalu,vfwmul,vfsqrt,vfrecp,vfsgnj,vfcmp,\
vfmerge,vfcvtitof,vfcvtftoi,vfwcvtitof,\
vfwcvtftoi,vfwcvtftof,vfncvtitof,vfncvtftoi,\
- vfncvtftof,vfmuladd,vfwmuladd,vfclass")
+ vfncvtftof,vfmuladd,vfwmuladd,vfclass,vired,
+ viwred,vfredu,vfredo,vfwredu,vfwredo")
(const_int INVALID_ATTRIBUTE)
(eq_attr "mode" "VNx1QI,VNx1BI")
(symbol_ref "riscv_vector::get_ratio(E_VNx1QImode)")
viwmul,vnshift,vaalu,vsmul,vsshift,vnclip,vmsfs,\
vmiota,vmidx,vfalu,vfmul,vfminmax,vfdiv,vfwalu,vfwmul,\
vfsqrt,vfrecp,vfsgnj,vfcmp,vfcvtitof,vfcvtftoi,vfwcvtitof,\
- vfwcvtftoi,vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,vfclass")
+ vfwcvtftoi,vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,vfclass,\
+ vired,viwred,vfredu,vfredo,vfwredu,vfwredo")
(const_int 2)
(eq_attr "type" "vimerge,vfmerge")
(eq_attr "type" "vldux,vldox,vialu,vshift,viminmax,vimul,vidiv,vsalu,\
viwalu,viwmul,vnshift,vimerge,vaalu,vsmul,\
vsshift,vnclip,vfalu,vfmul,vfminmax,vfdiv,vfwalu,vfwmul,\
- vfsgnj,vfmerge")
+ vfsgnj,vfmerge,vired,viwred,vfredu,vfredo,vfwredu,vfwredo")
(const_int 5)
(eq_attr "type" "vicmp,vimuladd,viwmuladd,vfcmp,vfmuladd,vfwmuladd")
(eq_attr "type" "vldux,vldox,vialu,vshift,viminmax,vimul,vidiv,vsalu,\
viwalu,viwmul,vnshift,vimerge,vaalu,vsmul,\
vsshift,vnclip,vfalu,vfmul,vfminmax,vfdiv,\
- vfwalu,vfwmul,vfsgnj,vfmerge")
+ vfwalu,vfwmul,vfsgnj,vfmerge,vired,viwred,vfredu,\
+ vfredo,vfwredu,vfwredo")
(symbol_ref "riscv_vector::get_ta(operands[6])")
(eq_attr "type" "vimuladd,viwmuladd,vfmuladd,vfwmuladd")
(define_attr "avl_type" ""
(cond [(eq_attr "type" "vlde,vlde,vste,vimov,vimov,vimov,vfmov,vext,vimerge,\
vfsqrt,vfrecp,vfmerge,vfcvtitof,vfcvtftoi,vfwcvtitof,\
- vfwcvtftoi,vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,vfclass")
+ vfwcvtftoi,vfwcvtftof,vfncvtitof,vfncvtftoi,vfncvtftof,\
+ vfclass,vired,viwred,vfredu,vfredo,vfwredu,vfwredo")
(symbol_ref "INTVAL (operands[7])")
(eq_attr "type" "vldm,vstm,vimov,vmalu,vmalu")
(symbol_ref "INTVAL (operands[5])")
"vfncvt.rod.f.f.w\t%0,%3%p1"
[(set_attr "type" "vfncvtftof")
(set_attr "mode" "<V_DOUBLE_TRUNC>")])
+
+;; -------------------------------------------------------------------------------
+;; ---- Predicated reduction operations
+;; -------------------------------------------------------------------------------
+;; Includes:
+;; - 14.1 Vector Single-Width Integer Reduction Instructions
+;; - 14.2 Vector Widening Integer Reduction Instructions
+;; - 14.3 Vector Single-Width Floating-Point Reduction Instructions
+;; - 14.4 Vector Widening Floating-Point Reduction Instructions
+;; -------------------------------------------------------------------------------
+
+;; For reduction operations, we should have seperate patterns for
+;; TARGET_MIN_VLEN == 32 and TARGET_MIN_VLEN > 32.
+;; Since reduction need LMUL = 1 scalar operand as the input operand
+;; and they are different.
+;; For example, The LMUL = 1 corresponding mode of VNx16QImode is VNx4QImode
+;; for -march=rv*zve32* wheras VNx8QImode for -march=rv*zve64*
+(define_insn "@pred_reduc_<reduc><mode><vlmul1>"
+ [(set (match_operand:<VLMUL1> 0 "register_operand" "=vd, vr")
+ (unspec:<VLMUL1>
+ [(unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK")
+ (match_operand 6 "const_int_operand" " i, i")
+ (match_operand 7 "const_int_operand" " i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (any_reduc:VI
+ (vec_duplicate:VI
+ (vec_select:<VEL>
+ (match_operand:<VLMUL1> 4 "register_operand" " vr, vr")
+ (parallel [(const_int 0)])))
+ (match_operand:VI 3 "register_operand" " vr, vr"))
+ (match_operand:<VLMUL1> 2 "vector_merge_operand" "0vu,0vu")] UNSPEC_REDUC))]
+ "TARGET_VECTOR && TARGET_MIN_VLEN > 32"
+ "vred<reduc>.vs\t%0,%3,%4%p1"
+ [(set_attr "type" "vired")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_reduc_<reduc><mode><vlmul1_zve32>"
+ [(set (match_operand:<VLMUL1_ZVE32> 0 "register_operand" "=vd, vr")
+ (unspec:<VLMUL1_ZVE32>
+ [(unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK")
+ (match_operand 6 "const_int_operand" " i, i")
+ (match_operand 7 "const_int_operand" " i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (any_reduc:VI_ZVE32
+ (vec_duplicate:VI_ZVE32
+ (vec_select:<VEL>
+ (match_operand:<VLMUL1_ZVE32> 4 "register_operand" " vr, vr")
+ (parallel [(const_int 0)])))
+ (match_operand:VI_ZVE32 3 "register_operand" " vr, vr"))
+ (match_operand:<VLMUL1_ZVE32> 2 "vector_merge_operand" "0vu,0vu")] UNSPEC_REDUC))]
+ "TARGET_VECTOR && TARGET_MIN_VLEN == 32"
+ "vred<reduc>.vs\t%0,%3,%4%p1"
+ [(set_attr "type" "vired")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1>"
+ [(set (match_operand:<VWLMUL1> 0 "register_operand" "=&vr")
+ (unspec:<VWLMUL1>
+ [(unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+ (match_operand 5 "vector_length_operand" " rK")
+ (match_operand 6 "const_int_operand" " i")
+ (match_operand 7 "const_int_operand" " i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (match_operand:VWI 3 "register_operand" " vr")
+ (match_operand:<VWLMUL1> 4 "register_operand" " vr")
+ (match_operand:<VWLMUL1> 2 "vector_merge_operand" " 0vu")] WREDUC))]
+ "TARGET_VECTOR && TARGET_MIN_VLEN > 32"
+ "vwredsum<v_su>.vs\t%0,%3,%4%p1"
+ [(set_attr "type" "viwred")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_widen_reduc_plus<v_su><mode><vwlmul1_zve32>"
+ [(set (match_operand:<VWLMUL1_ZVE32> 0 "register_operand" "=&vr")
+ (unspec:<VWLMUL1_ZVE32>
+ [(unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+ (match_operand 5 "vector_length_operand" " rK")
+ (match_operand 6 "const_int_operand" " i")
+ (match_operand 7 "const_int_operand" " i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (match_operand:VWI_ZVE32 3 "register_operand" " vr")
+ (match_operand:<VWLMUL1_ZVE32> 4 "register_operand" " vr")
+ (match_operand:<VWLMUL1_ZVE32> 2 "vector_merge_operand" " 0vu")] WREDUC))]
+ "TARGET_VECTOR && TARGET_MIN_VLEN == 32"
+ "vwredsum<v_su>.vs\t%0,%3,%4%p1"
+ [(set_attr "type" "viwred")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_reduc_<reduc><mode><vlmul1>"
+ [(set (match_operand:<VLMUL1> 0 "register_operand" "=vd, vr")
+ (unspec:<VLMUL1>
+ [(unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK")
+ (match_operand 6 "const_int_operand" " i, i")
+ (match_operand 7 "const_int_operand" " i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (any_freduc:VF
+ (vec_duplicate:VF
+ (vec_select:<VEL>
+ (match_operand:<VLMUL1> 4 "register_operand" " vr, vr")
+ (parallel [(const_int 0)])))
+ (match_operand:VF 3 "register_operand" " vr, vr"))
+ (match_operand:<VLMUL1> 2 "vector_merge_operand" "0vu,0vu")] UNSPEC_REDUC))]
+ "TARGET_VECTOR && TARGET_MIN_VLEN > 32"
+ "vfred<reduc>.vs\t%0,%3,%4%p1"
+ [(set_attr "type" "vfredu")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_reduc_<reduc><mode><vlmul1_zve32>"
+ [(set (match_operand:<VLMUL1_ZVE32> 0 "register_operand" "=vd, vr")
+ (unspec:<VLMUL1_ZVE32>
+ [(unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK")
+ (match_operand 6 "const_int_operand" " i, i")
+ (match_operand 7 "const_int_operand" " i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (any_freduc:VF_ZVE32
+ (vec_duplicate:VF_ZVE32
+ (vec_select:<VEL>
+ (match_operand:<VLMUL1_ZVE32> 4 "register_operand" " vr, vr")
+ (parallel [(const_int 0)])))
+ (match_operand:VF_ZVE32 3 "register_operand" " vr, vr"))
+ (match_operand:<VLMUL1_ZVE32> 2 "vector_merge_operand" "0vu,0vu")] UNSPEC_REDUC))]
+ "TARGET_VECTOR && TARGET_MIN_VLEN == 32"
+ "vfred<reduc>.vs\t%0,%3,%4%p1"
+ [(set_attr "type" "vfredu")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_reduc_plus<order><mode><vlmul1>"
+ [(set (match_operand:<VLMUL1> 0 "register_operand" "=vd, vr")
+ (unspec:<VLMUL1>
+ [(unspec:<VLMUL1>
+ [(unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK")
+ (match_operand 6 "const_int_operand" " i, i")
+ (match_operand 7 "const_int_operand" " i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (plus:VF
+ (vec_duplicate:VF
+ (vec_select:<VEL>
+ (match_operand:<VLMUL1> 4 "register_operand" " vr, vr")
+ (parallel [(const_int 0)])))
+ (match_operand:VF 3 "register_operand" " vr, vr"))
+ (match_operand:<VLMUL1> 2 "vector_merge_operand" "0vu,0vu")] UNSPEC_REDUC)] ORDER))]
+ "TARGET_VECTOR && TARGET_MIN_VLEN > 32"
+ "vfred<order>sum.vs\t%0,%3,%4%p1"
+ [(set_attr "type" "vfred<order>")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_reduc_plus<order><mode><vlmul1_zve32>"
+ [(set (match_operand:<VLMUL1_ZVE32> 0 "register_operand" "=vd, vr")
+ (unspec:<VLMUL1_ZVE32>
+ [(unspec:<VLMUL1_ZVE32>
+ [(unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" " vm,Wc1")
+ (match_operand 5 "vector_length_operand" " rK, rK")
+ (match_operand 6 "const_int_operand" " i, i")
+ (match_operand 7 "const_int_operand" " i, i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (plus:VF_ZVE32
+ (vec_duplicate:VF_ZVE32
+ (vec_select:<VEL>
+ (match_operand:<VLMUL1_ZVE32> 4 "register_operand" " vr, vr")
+ (parallel [(const_int 0)])))
+ (match_operand:VF_ZVE32 3 "register_operand" " vr, vr"))
+ (match_operand:<VLMUL1_ZVE32> 2 "vector_merge_operand" "0vu,0vu")] UNSPEC_REDUC)] ORDER))]
+ "TARGET_VECTOR && TARGET_MIN_VLEN == 32"
+ "vfred<order>sum.vs\t%0,%3,%4%p1"
+ [(set_attr "type" "vfred<order>")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "@pred_widen_reduc_plus<order><mode><vwlmul1>"
+ [(set (match_operand:<VWLMUL1> 0 "register_operand" "=&vr")
+ (unspec:<VWLMUL1>
+ [(unspec:<VWLMUL1>
+ [(unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand" "vmWc1")
+ (match_operand 5 "vector_length_operand" " rK")
+ (match_operand 6 "const_int_operand" " i")
+ (match_operand 7 "const_int_operand" " i")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (match_operand:VWF 3 "register_operand" " vr")
+ (match_operand:<VWLMUL1> 4 "register_operand" " vr")
+ (match_operand:<VWLMUL1> 2 "vector_merge_operand" " 0vu")] UNSPEC_WREDUC_SUM)] ORDER))]
+ "TARGET_VECTOR && TARGET_MIN_VLEN > 32"
+ "vfwred<order>sum.vs\t%0,%3,%4%p1"
+ [(set_attr "type" "vfwred<order>")
+ (set_attr "mode" "<MODE>")])