https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123027

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Priority|P3                          |P2
                 CC|                            |crazylht at gmail dot com,
                   |                            |rguenth at gcc dot gnu.org
             Target|                            |x86_64-*-*
     Ever confirmed|0                           |1
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2025-12-07

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
For "reasons" RTL expansion differs here, using a jumpy sequence w/o
-ffinite-math-only, but an if-converted variant if not.  IIRC this is the x86
expander which likely fails to recognize equal compare args and thus
min/max.  IIRC there's another PR for this already.

TER should come to the rescue here.  The x86 backend gets

(ge (reg/v:SF 100 [ a ])
    (reg/v:SF 101 [ b ])) ? (reg/v:SF 101 [ b ]) : (reg/v:SF 100 [ a ])

then decides to turn this into (le ...) ? : instead of inverting the compare
(which should be valid with -ffinite-math-only) and ix86_expand_sse_fp_minmax
does not recognize the LE min():

static bool
ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code, rtx cmp_op0,
                           rtx cmp_op1, rtx if_true, rtx if_false)
{
  machine_mode mode;
  bool is_min;
  rtx tmp;

  if (code == LT)
    ;
  else if (code == UNGE)
    std::swap (if_true, if_false);
  else
    return false;

this could add 

  else if (code == LE && !HONOR_NANS (mode))
    ;

I'll note that we end up with GE only because of prepare_cmp_insn not
accepting LT for cbranch but GE is and what reversed_comparison_code_parts
does depends on HONOR_NANS.

The following works for me:

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index fd9bcaa8541..da96454a73a 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -4163,7 +4163,8 @@ ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code,
rtx cmp_op0,
   bool is_min;
   rtx tmp;

-  if (code == LT)
+  mode = GET_MODE (dest);
+  if (code == LT || (code == LE && !HONOR_NANS (mode)))
     ;
   else if (code == UNGE)
     std::swap (if_true, if_false);
@@ -4177,7 +4178,6 @@ ix86_expand_sse_fp_minmax (rtx dest, enum rtx_code code,
rtx cmp_op0,
   else
     return false;

-  mode = GET_MODE (dest);
   if (immediate_operand (if_false, mode))
     if_false = force_reg (mode, if_false);
   if (immediate_operand (if_true, mode))

Reply via email to