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))