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

Reply via email to