}
[(set_attr "type" "viwmuladd")])
+(define_insn_and_split "*pred_cmp_swapped<mode>_scalar"
+ [(set (match_operand:<VM> 0 "register_operand")
+ (if_then_else:<VM>
+ (unspec:<VM>
+ [(match_operand:<VM> 1 "vector_mask_operand")
+ (match_operand 6 "vector_length_operand")
+ (match_operand 7 "const_int_operand")
+ (match_operand 8 "const_int_operand")
+ (reg:SI VL_REGNUM)
+ (reg:SI VTYPE_REGNUM)] UNSPEC_VPREDICATE)
+ (match_operator:<VM> 3 "comparison_swappable_operator"
+ [(vec_duplicate:V_VLSI
+ (match_operand:<VEL> 4 "register_operand"))
+ (match_operand:V_VLSI 5 "register_operand")])
+ (unspec:<VM>
+ [(match_operand:DI 2 "register_operand")] UNSPEC_VUNDEF)))]
+ "TARGET_VECTOR && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ riscv_vector::expand_vx_cmp_vec_dup_vec (operands[0], operands[4],
+ operands[5],
+ GET_CODE (operands[3]),
+ <MODE>mode);
+
+ DONE;
+ }
+ [(set_attr "type" "vicmp")])
+
;; =============================================================================
;; Combine vec_duplicate + op.vv to op.vf
;; Include
(define_predicate "comparison_except_ge_operator"
(match_code "eq,ne,le,leu,gt,gtu,lt,ltu"))
+(define_predicate "comparison_swappable_operator"
+ (match_code "gtu"))
+
(define_predicate "ge_operator"
(match_code "ge,geu"))
void expand_vx_binary_vec_vec_dup (rtx, rtx, rtx, rtx_code, machine_mode);
void expand_vx_binary_vxrm_vec_vec_dup (rtx, rtx, rtx, int, int, machine_mode);
void expand_vx_binary_vxrm_vec_dup_vec (rtx, rtx, rtx, int, int, machine_mode);
+void expand_vx_cmp_vec_dup_vec (rtx, rtx, rtx, rtx_code, machine_mode);
#endif
bool sew64_scalar_helper (rtx *, rtx *, rtx, machine_mode,
bool, void (*)(rtx *, rtx), enum avl_type);
emit_vlmax_insn (icode, riscv_vector::BINARY_OP, ops);
}
+static rtx_code
+get_swapped_cmp_rtx_code (rtx_code code)
+{
+ switch (code)
+ {
+ case GTU:
+ return LTU;
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Expand the binary vx combine with the format like v2 = vec_dup(x) > v1.
+ Aka the first op comes from the vec_duplicate, and the second op is the vector
+ reg. Unfortunately, the RVV vms* only form like v2 = v1 < vec_dup(x), so
+ we need to swap the op_1 and op_2, then emit the swapped(from gtu to ltu)
+ insn instead. */
+
+void
+expand_vx_cmp_vec_dup_vec (rtx op_0, rtx op_1, rtx op_2, rtx_code code,
+ machine_mode mode)
+{
+ machine_mode mask_mode = get_mask_mode (mode);
+ rtx_code swapped_code = get_swapped_cmp_rtx_code (code);
+
+ insn_code icode = code_for_pred_cmp_scalar (mode);
+ rtx cmp = gen_rtx_fmt_ee (swapped_code, mask_mode, op_2, op_1);
+ rtx ops[] = {op_0, cmp, op_2, op_1};
+
+ emit_vlmax_insn (icode, COMPARE_OP, ops);
+}
+
/* Vectorize popcount by the Wilkes-Wheeler-Gill algorithm that libgcc uses as
well. */
void