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

Reply via email to