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