On Mon, Dec 8, 2025 at 5:42 PM Richard Biener <[email protected]> wrote: > > When we get a <= b ? b : a into ix86_expand_sse_fp_minmax we can > swap and invert this with -ffinite-math-only to get a < b ? a : b. > > Bootstrap and regtest running on x86_64-unknown-linux-gnu. I've > added a runtime testcase showing we do have to swap both to > get signed zeros correct. UNGT, etc. do not appear with > -ffinite-math-only, at least I failed to create a testcase. > We could invert UNGT to LE and then do the same trick as for LE. > > Bootstrap and regtest running on x86_64-unknown-linux-gnu. > > OK if that succeeds? Ok. > > Thanks, > Richard. > > PR target/123027 > * config/i386/i386-expand.cc (ix86_expand_sse_fp_minmax): > With !HONOR_NANS we can handle LE by swapping and inverting. > > * gcc.target/i386/pr123027.c: New testcase. > * gcc.dg/torture/pr123027.c: Likewise. > --- > gcc/config/i386/i386-expand.cc | 9 +++++++-- > gcc/testsuite/gcc.dg/torture/pr123027.c | 20 ++++++++++++++++++++ > gcc/testsuite/gcc.target/i386/pr123027.c | 15 +++++++++++++++ > 3 files changed, 42 insertions(+), 2 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/torture/pr123027.c > create mode 100644 gcc/testsuite/gcc.target/i386/pr123027.c > > diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc > index fd9bcaa8541..438fa4e4b6a 100644 > --- a/gcc/config/i386/i386-expand.cc > +++ b/gcc/config/i386/i386-expand.cc > @@ -4159,12 +4159,18 @@ 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; > + machine_mode mode = GET_MODE (dest); > bool is_min; > rtx tmp; > > if (code == LT) > ; > + else if (code == LE && !HONOR_NANS (mode)) > + { > + /* We can swap LE to GE and then invert to LT. */ > + std::swap (cmp_op0, cmp_op1); > + std::swap (if_true, if_false); > + } > else if (code == UNGE) > std::swap (if_true, if_false); > else > @@ -4177,7 +4183,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)) > diff --git a/gcc/testsuite/gcc.dg/torture/pr123027.c > b/gcc/testsuite/gcc.dg/torture/pr123027.c > new file mode 100644 > index 00000000000..cba4cc9792e > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/torture/pr123027.c > @@ -0,0 +1,20 @@ > +/* { dg-do run } */ > +/* { dg-options "-ffinite-math-only" } */ > +/* { dg-add-options ieee } */ > + > +double a = 0.0; > +double b = -0.0; > + > +int main() > +{ > + double min1 = a < b ? a : b; > + double max1 = a > b ? a : b; > + double min2 = b < a ? b : a; > + double max2 = b > a ? b : a; > + if (__builtin_copysign (1., min1) != -1. > + || __builtin_copysign (1., max1) != -1. > + || __builtin_copysign (1., min2) != 1. > + || __builtin_copysign (1., max2) != 1.) > + __builtin_abort (); > + return 0; > +} > diff --git a/gcc/testsuite/gcc.target/i386/pr123027.c > b/gcc/testsuite/gcc.target/i386/pr123027.c > new file mode 100644 > index 00000000000..e04fc807a07 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr123027.c > @@ -0,0 +1,15 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -msse -ffinite-math-only" } */ > + > +float foo (float a, float b) > +{ > + return a < b ? a : b; > +} > + > +float bar (float a, float b) > +{ > + return a > b ? a : b; > +} > + > +/* { dg-final { scan-assembler-times "minss" 1 } } */ > +/* { dg-final { scan-assembler-times "maxss" 1 } } */ > -- > 2.51.0
-- BR, Hongtao
