Hi, Following the discussion in pr116738, the insn for UNSPEC_IEEE_MAXMIN actually matches the behavior of if_then_else, so remove the UNSPEC and rewrite related pattern with if_then_else.
Bootstrapped & regtested on x86-64-pc-linux-gnu. Ok for trunk? gcc/ChangeLog: * config/i386/i386-expand.cc (ix86_expand_sse_fp_minmax): Emit if_then_else pattern instead of UNSPEC. * config/i386/i386.md (UNSPEC_IEEE_MIN): Removed. (UNSPEC_IEEE_MAX): Likewise. (IEEE_MAXMIN): Likewise. (ieee_maxmin_cmp): New code iterator. (ieee_maxmin): Change to match ieee_maxmin_cmp. (*ieee_s<ieee_maxmin>hf3): Removed. (*ieee_s<ieee_maxmin><mode>3): Rewrite as if_then_else, use MODEFH as and SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P as condition. (*ieee_max<mode>3_1): Adjust split output to if_then_else. (*ieee_min<mode>3_1): Likewise. * config/i386/mmx.md (mmx_ieee_<ieee_maxmin>v2sf3): Rewrite as if_then_else. * config/i386/sse.md : (*minmax<mode>3_1): Adjust split to emit if_then_else. (*minmax<mode>3_2): Likewise. (ieee_<ieee_maxmin><mode>3<mask_name><round_saeonly_name>): Rewrite as if_then_else. (*ieee_<ieee_maxmin><mode>3): Likewise. (<sse>_ieee_vm<ieee_maxmin><mode>3<mask_scalar_name><round_saeonly_scalar_name>): Likewise. --- gcc/config/i386/i386-expand.cc | 9 +++-- gcc/config/i386/i386.md | 58 ++++++++++++------------------- gcc/config/i386/mmx.md | 10 +++--- gcc/config/i386/sse.md | 62 ++++++++++++++++++++-------------- 4 files changed, 69 insertions(+), 70 deletions(-) diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index a6e6e738a52..e8feb7c29f0 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -4144,12 +4144,11 @@ ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code, rtx cmp_op0, but MODE may be a vector mode and thus not appropriate. */ if (!flag_finite_math_only || flag_signed_zeros) { - int u = is_min ? UNSPEC_IEEE_MIN : UNSPEC_IEEE_MAX; - rtvec v; - + rtx cmp; + code = is_min ? UNGE : GE; if_true = force_reg (mode, if_true); - v = gen_rtvec (2, if_true, if_false); - tmp = gen_rtx_UNSPEC (mode, v, u); + cmp = gen_rtx_fmt_ee (code, mode, if_true, if_false); + tmp = gen_rtx_IF_THEN_ELSE (mode, cmp, if_true, if_false); } else { diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 03b0f548467..0eb3b9cf1fa 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -143,10 +143,6 @@ (define_c_enum "unspec" [ UNSPEC_CVTBFSF UNSPEC_COMX - ;; Generic math support - UNSPEC_IEEE_MIN ; not commutative - UNSPEC_IEEE_MAX ; not commutative - ;; x87 Floating point UNSPEC_SIN UNSPEC_COS @@ -1045,13 +1041,11 @@ (define_code_attr maxmin_int [(smax "maxs") (smin "mins") (umax "maxu") (umin "minu")]) (define_code_attr maxmin_float [(smax "max") (smin "min")]) -(define_int_iterator IEEE_MAXMIN - [UNSPEC_IEEE_MAX - UNSPEC_IEEE_MIN]) +;; Non-commutative ieee maxmin operation can be if_then_else. +(define_code_iterator ieee_maxmin_cmp [unge ge]) -(define_int_attr ieee_maxmin - [(UNSPEC_IEEE_MAX "max") - (UNSPEC_IEEE_MIN "min")]) +(define_code_attr ieee_maxmin + [(unge "min") (ge "max")]) ;; Mapping of logic operators (define_code_iterator any_logic [and ior xor]) @@ -26395,25 +26389,15 @@ (define_insn "<code>hf3" ;; Their operands are not commutative, and thus they may be used in the ;; presence of -0.0 and NaN. -(define_insn "*ieee_s<ieee_maxmin>hf3" - [(set (match_operand:HF 0 "register_operand" "=v") - (unspec:HF - [(match_operand:HF 1 "register_operand" "v") - (match_operand:HF 2 "nonimmediate_operand" "vm")] - IEEE_MAXMIN))] - "TARGET_AVX512FP16" - "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}" - [(set_attr "prefix" "evex") - (set_attr "type" "sseadd") - (set_attr "mode" "HF")]) - (define_insn "*ieee_s<ieee_maxmin><mode>3" - [(set (match_operand:MODEF 0 "register_operand" "=x,v") - (unspec:MODEF - [(match_operand:MODEF 1 "register_operand" "0,v") - (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")] - IEEE_MAXMIN))] - "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH" + [(set (match_operand:MODEFH 0 "register_operand" "=x,v") + (if_then_else:MODEFH + (ieee_maxmin_cmp:MODEFH + (match_operand:MODEFH 1 "register_operand" "0,v") + (match_operand:MODEFH 2 "nonimmediate_operand" "xm,vm")) + (match_dup 1) + (match_dup 2)))] + "SSE_FLOAT_MODE_SSEMATH_OR_HFBF_P (<MODE>mode)" "@ <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2} v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" @@ -26439,10 +26423,11 @@ (define_insn_and_split "*ieee_max<mode>3_1" "#" "&& 1" [(set (match_dup 0) - (unspec:MODEF - [(match_dup 2) - (match_dup 1)] - UNSPEC_IEEE_MAX))]) + (if_then_else:MODEF + (ge:MODEF (match_dup 2) + (match_dup 1)) + (match_dup 2) + (match_dup 1)))]) (define_insn_and_split "*ieee_min<mode>3_1" [(set (match_operand:MODEF 0 "register_operand") @@ -26460,10 +26445,11 @@ (define_insn_and_split "*ieee_min<mode>3_1" "#" "&& 1" [(set (match_dup 0) - (unspec:MODEF - [(match_dup 2) - (match_dup 1)] - UNSPEC_IEEE_MIN))]) + (if_then_else:MODEF + (unge:MODEF (match_dup 2) + (match_dup 1)) + (match_dup 2) + (match_dup 1)))]) ;; Make two stack loads independent: ;; fld aa fld aa diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md index 61a4f4d21ea..497dcffbca4 100644 --- a/gcc/config/i386/mmx.md +++ b/gcc/config/i386/mmx.md @@ -868,10 +868,12 @@ (define_insn "*mmx_<code>v2sf3" (define_insn "mmx_ieee_<ieee_maxmin>v2sf3" [(set (match_operand:V2SF 0 "register_operand" "=y") - (unspec:V2SF - [(match_operand:V2SF 1 "register_operand" "0") - (match_operand:V2SF 2 "nonimmediate_operand" "ym")] - IEEE_MAXMIN))] + (if_then_else:V2SF + (ieee_maxmin_cmp:V2SF + (match_operand:V2SF 1 "register_operand" "0") + (match_operand:V2SF 2 "nonimmediate_operand" "ym")) + (match_dup 1) + (match_dup 2)))] "TARGET_3DNOW" "pf<ieee_maxmin>\t{%2, %0|%0, %2}" [(set_attr "type" "mmxadd") diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index efe32e5149f..b1859ca68db 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -3336,15 +3336,18 @@ (define_insn_and_split "*minmax<mode>3_1" "&& 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; + rtx_code c = UNGE; + if ((INTVAL (operands[5]) == 1 + && rtx_equal_p (operands[1], operands[4])) + || (INTVAL (operands[5]) == 14 + && rtx_equal_p (operands[1], operands[3]))) + c = GE; 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); + rtx cmp = gen_rtx_fmt_ee (c, <MODE>mode, operands[1], operands[2]); + rtx tmp = gen_rtx_IF_THEN_ELSE (<MODE>mode, cmp, operands[2], + operands[1]); emit_move_insn (operands[0], tmp); DONE; }) @@ -3367,14 +3370,15 @@ (define_insn_and_split "*minmax<mode>3_2" "&& 1" [(const_int 0)] { - int u = UNSPEC_IEEE_MIN; + rtx_code c = UNGE; if (rtx_equal_p (operands[1], operands[3])) - u = UNSPEC_IEEE_MAX; + c = GE; if (MEM_P (operands[2])) - 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); + operands[2] = force_reg (<MODE>mode, operands[1]); + rtx cmp = gen_rtx_fmt_ee (c, <MODE>mode, operands[2], operands[1]); + rtx tmp = gen_rtx_IF_THEN_ELSE (<MODE>mode, cmp, operands[2], + operands[1]); emit_move_insn (operands[0], tmp); DONE; }) @@ -3387,10 +3391,12 @@ (define_insn_and_split "*minmax<mode>3_2" (define_insn "ieee_<ieee_maxmin><mode>3<mask_name><round_saeonly_name>" [(set (match_operand:VFH 0 "register_operand" "=x,v") - (unspec:VFH - [(match_operand:VFH 1 "register_operand" "0,v") - (match_operand:VFH 2 "<round_saeonly_nimm_predicate>" "xBm,<round_saeonly_constraint>")] - IEEE_MAXMIN))] + (if_then_else:VFH + (ieee_maxmin_cmp:VFH + (match_operand:VFH 1 "register_operand" "0,v") + (match_operand:VFH 2 "<round_saeonly_nimm_predicate>" "xBm,<round_saeonly_constraint>")) + (match_dup 1) + (match_dup 2)))] "TARGET_SSE && <mask_mode512bit_condition> && <round_saeonly_mode_condition>" @@ -3409,12 +3415,16 @@ (define_insn "*ieee_<ieee_maxmin><mode>3" [(set (match_operand:VFH_128 0 "register_operand" "=x,v") (vec_merge:VFH_128 (vec_duplicate:VFH_128 - (unspec:<ssescalarmode> - [(vec_select:<ssescalarmode> - (match_operand:VFH_128 1 "register_operand" "0,v") - (parallel [(const_int 0)])) - (match_operand:<ssescalarmode> 2 "nonimmediate_operand" "xm,vm")] - IEEE_MAXMIN)) + (if_then_else:<ssescalarmode> + (ieee_maxmin_cmp:<ssescalarmode> + (vec_select:<ssescalarmode> + (match_operand:VFH_128 1 "register_operand" "0,v") + (parallel [(const_int 0)])) + (match_operand:<ssescalarmode> 2 "nonimmediate_operand" "xm,vm")) + (vec_select:<ssescalarmode> + (match_dup 1) + (parallel [(const_int 0)])) + (match_dup 2))) (match_dup 1) (const_int 1)))] "TARGET_SSE" @@ -3477,10 +3487,12 @@ (define_insn "*<sse>_vm<code><mode>3<mask_scalar_name><round_saeonly_scalar_name (define_insn "<sse>_ieee_vm<ieee_maxmin><mode>3<mask_scalar_name><round_saeonly_scalar_name>" [(set (match_operand:VFH_128 0 "register_operand" "=x,v") (vec_merge:VFH_128 - (unspec:VFH_128 - [(match_operand:VFH_128 1 "register_operand" "0,v") - (match_operand:VFH_128 2 "nonimmediate_operand" "xm,<round_saeonly_scalar_constraint>")] - IEEE_MAXMIN) + (if_then_else:VFH_128 + (ieee_maxmin_cmp:VFH_128 + (match_operand:VFH_128 1 "register_operand" "0,v") + (match_operand:VFH_128 2 "nonimmediate_operand" "xm,<round_saeonly_scalar_constraint>")) + (match_dup 1) + (match_dup 2)) (match_dup 1) (const_int 1)))] "TARGET_SSE" -- 2.31.1