@@ -3064,6 +3064,69 @@ (define_insn "*<code><mode>3<mask_name><round_saeonly_name>"
(set_attr "prefix" "<mask_prefix3>")
(set_attr "mode" "<MODE>")])
+(define_insn_and_split "*minmax<mode>3_1"
+ [(set (match_operand:VFH 0 "register_operand")
+ (vec_merge:VFH
+ (match_operand:VFH 1 "nonimmediate_operand")
+ (match_operand:VFH 2 "nonimmediate_operand")
+ (unspec:<avx512fmaskmode>
+ [(match_operand:VFH 3 "nonimmediate_operand")
+ (match_operand:VFH 4 "nonimmediate_operand")
+ (match_operand:SI 5 "const_0_to_31_operand")]
+ UNSPEC_PCMP)))]
+ "TARGET_SSE && ix86_pre_reload_split ()
+ && ((rtx_equal_p (operands[1], operands[3])
+ && rtx_equal_p (operands[2], operands[4]))
+ || (rtx_equal_p (operands[1], operands[4])
+ && rtx_equal_p (operands[2], operands[3])))
+ && (INTVAL (operands[5]) == 1 || INTVAL (operands[5]) == 14)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ int u = UNSPEC_IEEE_MIN;
+ if ((INTVAL (operands[5]) == 1 && rtx_equal_p (operands[1], operands[4]))
+ || (INTVAL (operands[5]) == 14 && rtx_equal_p (operands[1], operands[3])))
+ u = UNSPEC_IEEE_MAX;
+
+ if (MEM_P (operands[1]))
+ operands[1] = force_reg (<MODE>mode, operands[1]);
+ rtvec v = gen_rtvec (2, operands[1], operands[2]);
+ rtx tmp = gen_rtx_UNSPEC (<MODE>mode, v, u);
+ emit_move_insn (operands[0], tmp);
+ DONE;
+ })
+
+(define_insn_and_split "*minmax<mode>3_2"
+ [(set (match_operand:VF_128_256 0 "register_operand")
+ (unspec:VF_128_256
+ [(match_operand:VF_128_256 1 "nonimmediate_operand")
+ (match_operand:VF_128_256 2 "nonimmediate_operand")
+ (lt:VF_128_256
+ (match_operand:VF_128_256 3 "nonimmediate_operand")
+ (match_operand:VF_128_256 4 "nonimmediate_operand"))]
+ UNSPEC_BLENDV))]
+ "TARGET_SSE && ix86_pre_reload_split ()
+ && ((rtx_equal_p (operands[1], operands[3])
+ && rtx_equal_p (operands[2], operands[4]))
+ || (rtx_equal_p (operands[1], operands[4])
+ && rtx_equal_p (operands[2], operands[3])))"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+ {
+ int u = UNSPEC_IEEE_MIN;
+ if (rtx_equal_p (operands[1], operands[3]))
+ u = UNSPEC_IEEE_MAX;
+
+ if (MEM_P (operands[2]))
+ force_reg (<MODE>mode, operands[2]);
+ rtvec v = gen_rtvec (2, operands[2], operands[1]);
+ rtx tmp = gen_rtx_UNSPEC (<MODE>mode, v, u);
+ emit_move_insn (operands[0], tmp);
+ DONE;
+ })
+
;; These versions of the min/max patterns implement exactly the operations
;; min = (op1 < op2 ? op1 : op2)
;; max = (!(op1 < op2) ? op1 : op2)