Doh!  Wrong patch...

> -----Original Message-----
> From: Roger Sayle <[email protected]>
> Sent: 10 July 2026 17:48
> To: 'GCC Patches' <[email protected]>; 'Jeffrey Law'
> <[email protected]>; 'Andrea Pinski'
> <[email protected]>
> Subject: [PATCH v3] PR tree-opt/57371: Improved comparison of integers to FP
> constants.
> 
> 
> Hi Jeff and Andrea,
> 
> Now that Eikash's patch for PR tree-opt/125385 is in the tree, I've updated my
> (float)i == 4.0f patch against the current mainline.
> 
> The full technical description is in my post from July 2024:
> https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658482.html
> which was initially (positively) reviewed here:
> https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659433.html
> and my recent ping (which contained some more context) is at
> https://gcc.gnu.org/pipermail/gcc-patches/2026-June/720287.html
> 
> Eikash's patch/optimization is cool, and obsoletes all the ranger related 
> pieces of
> my original patch.  Thanks Eikash and Andrea.
> 
> This patch has been retested on x86_64-pc-linux-gnu with make bootstrap and
> make -k check, both with and without --target_board=unix{-m32} with no new
> failures.  Ok for mainline?
> 
> 
> 2026-07-10  Roger Sayle  <[email protected]>
> 
> gcc/ChangeLog
>         PR tree-optimization/57371
>         * fold-const.cc (fold_cmp_float_cst_p): New helper function.
>         * fold-const.h (fold_cmp_float_cst_p): Prototype here.
>         * match.pd ((FTYPE) N CMP CST): Use the new helper
>         fold_cmp_float_cst_p to check that transformation to an integer
>         comparison is safe.
> 
> gcc/testsuite/ChangeLog
>         PR tree-optimization/57371
>         * c-c++-common/pr57371-6.c: New test case.
>         * c-c++-common/pr57371-7.c: Likewise.
>         * c-c++-common/pr57371-8.c: Likewise.
>         * c-c++-common/pr57371-9.c: Likewise.
>         * c-c++-common/pr57371-10.c: Likewise.
> 
> 
> Thanks again,
> Roger
> --
> 
> > -----Original Message-----
> > From: Andrea Pinski <[email protected]>
> > Sent: 19 June 2026 07:32
> > To: Andrew Pinski <[email protected]>
> > Cc: Roger Sayle <[email protected]>; GCC Patches <gcc-
> > [email protected]>; Jeffrey Law <[email protected]>
> > Subject: Re: [PATCH] PR tree-opt/57371: Improved comparison of
> > integers to FP constants.
> >
> > On Mon, Jun 15, 2026 at 1:21 AM Andrew Pinski <[email protected]> wrote:
> > >
> > >
> > >
> > > On Mon, Jun 15, 2026, 1:09 AM Roger Sayle
> > > <[email protected]>
> > wrote:
> > >>
> > >>
> > >> Hi Jeff,
> > >> I'd like to ping/progress a patch of mine from July 2024:
> > >> https://gcc.gnu.org/pipermail/gcc-patches/2024-July/658482.html
> > >> which was initially (positively) reviewed here:
> > >> https://gcc.gnu.org/pipermail/gcc-patches/2024-August/659433.html
> > >>
> > >> The original motivation for this patch was Claudiu's issue/analysis
> > >> at
> > >> https://github.com/foss-for-synopsys-dwc-arc-processors/gcc/issues/
> > >> 11
> > >> 8 which predicted a dramatic +26% performance improvement on
> > >> EEMBC's
> > >> iirflt01 benchmark.
> > >>
> > >> A quick summary is that GCC currently fails to optimize:
> > >> int foo(long long x) { return x == 1.0; } to use an integral
> > >> comparison (and avoid a floating point conversion) because all the
> > >> values of long long can't be precisely represented as a (IEEE)
> > >> double.  This is too strict a condition, as only one value of a
> > >> "long long" gets converted to 1.0 (even with overflow and rounding).
> > >>
> > >> The code review above agreed the implementation itself is
> > >> reasonable and both machine and floating-point independent, the
> > >> challenge is in writing test cases for the code, which
> > >> unfortunately must assume a particular floating point format, and are
> therefore non-portable.
> > >>
> > >> To respond to Jeff's previous request/question, my preferred
> > >> solution is rather than try to add "-mieee" to these new test
> > >> cases, which should still pass even without strict IEEE (i.e. NaN)
> > >> support, and therefore we should still be testing with -O2 default
> > >> flags, but instead it makes sense for various backends to add
> > >> additional tests/copies to their gcc.target directories including
> > >> "-mieee", "-msoft-float", "-md-float", "-mg-float", "-mfpmath=387"
> > >> etc. if they so wish.  A failure of these tests does not indicate
> > >> an issue with the implementation, which simply uses the current
> > >> compile-time integer to FP (real) conversion support, but that that
> > >> test hasn't been ported to the new/native floating point format (say FP8 
> > >> or
> FP4).
> > >>
> > >> This patch has been retested on x86_64-pc-linux-gnu with make
> > >> bootstrap and make -k check, both with and without
> > >> --target_board=unix{-m32} with no new failures.  Ok for mainline
> > >> (cleaning up any testsuite wrinkles if/as they're reported)?
> > >>
> > >>
> > >> 2026-06-15  Roger Sayle  <[email protected]>
> > >>
> > >> gcc/ChangeLog
> > >>         PR tree-optimization/57371
> > >>         * fold-const.cc (fold_cmp_float_cst_p): New helper function.
> > >>         * fold-const.h (fold_cmp_float_cst_p): Prototype here.
> > >>         * match.pd ((FTYPE) N CMP CST): Use ranger to determine
> > >>         whether value is exactly representable by floating point type,
> > >>         and check flag_trapping_math if not.  Use the new helper
> > >>         fold_cmp_float_cst_p to check that transformation to an integer
> > >>         comparison is safe.
> > >
> > >
> > > Hmm, I have someone working on a related patch and this will conflict.
> > > We are changing (cmp (convert int) (float_cst)) to use the ranger
> > > and adding a
> > new function to the format helper to check if the range of the integer
> > can fit into the floating point exactly.
> > > The person working on this should be posting today or tomorrow.
> > > Since I helped with that patch I can review this one too.
> >
> > See https://gcc.gnu.org/pipermail/gcc-patches/2026-June/720633.html .
> > I do know there is some overlap between the 2 patches.
> > Like for an example in your patch you do:
> > ```
> >
> > +       if (!vr0.undefined_p ())
> > + {
> > +   lo = vr0.lower_bound ();
> > +   hi = vr0.upper_bound ();
> > +   int prec = (isign == SIGNED)
> > +      ? MAX (wi::min_precision (hi, SIGNED),
> > +     wi::min_precision (lo, SIGNED)) - 1
> > +      : wi::min_precision (hi, UNSIGNED);
> > +   wide_int nz = vr0.get_nonzero_bits ();
> > +   if (nz != 0)
> > +     prec -= wi::ctz (nz);
> > +   exact_p = prec <= significand_size (fmt); }
> > ``
> >
> > While Eikansh does:
> >
> > +#if GIMPLE
> > +       int_range_max vr;
> > +       if (!value_ok
> > +   && gimple_match_range_of_expr (vr, @0, @2))  value_ok =
> > +fmt.can_represent_integral_value_p (&vr); #endif
> >
> > And then can_represent_integral_value_p calls range_fits_type_p which
> > is basically what you do here (but better):
> > +   int prec = (isign == SIGNED)
> > +      ? MAX (wi::min_precision (hi, SIGNED),
> > +     wi::min_precision (lo, SIGNED)) - 1
> > +      : wi::min_precision (hi, UNSIGNED);
> > +   wide_int nz = vr0.get_nonzero_bits ();
> > +   if (nz != 0)
> > +     prec -= wi::ctz (nz);
> > +   exact_p = prec <= significand_size (fmt);
> >
> >
> >
> >
> > >
> > > Thanks,
> > > Andrea
> > >
> > >
> > >>
> > >> gcc/testsuite/ChangeLog
> > >>         PR tree-optimization/57371
> > >>         * c-c++-common/pr57371-6.c: New test case.
> > >>         * c-c++-common/pr57371-7.c: Likewise.
> > >>         * c-c++-common/pr57371-8.c: Likewise.
> > >>         * c-c++-common/pr57371-9.c: Likewise.
> > >>         * c-c++-common/pr57371-10.c: Likewise.
> > >>
> > >>
> > >> Thanks in advance,
> > >> Roger
> > >> --
> > >>
diff --git a/gcc/fold-const.cc b/gcc/fold-const.cc
index 1d0ed62a82f..b4e3a56aeb5 100644
--- a/gcc/fold-const.cc
+++ b/gcc/fold-const.cc
@@ -7020,6 +7020,92 @@ fold_real_zero_addition_p (const_tree type, const_tree 
arg,
   return negate || (arg && !tree_expr_maybe_real_minus_zero_p (arg));
 }
 
+/* Subroutine of match.pd that determines if it is safe to optimize
+   a floating point comparison of an integer value, known to be between
+   LO and HI, using comparison operator CMP, against the real constant
+   R in floating point type FMT, as the same integer comparison against
+   the integer constant I, with sign ISIGN.
+
+   For example, with IEEE-754, (float)x == 2.0f may replaced with x == 2
+   because the floating point representations of the neighboring integers
+   (float)1 and (float)3 are distinct from 2.0f, having values 1.0f and
+   3.0f respectively.  On the other hand (float)x == 16777220.0f can't
+   be replaced by x == 16777220 as (float)16777221 is also 1677220.0f
+   due to truncation/rounding.
+*/
+bool
+fold_cmp_float_cst_p (wide_int lo, wide_int hi, enum tree_code cmp,
+                     const REAL_VALUE_TYPE *r, format_helper fmt,
+                     wide_int i, signop isign)
+{
+  REAL_VALUE_TYPE raw;
+  REAL_VALUE_TYPE rnd;
+  bool check_im1 = true;
+  bool check_ip1 = true;
+
+  switch (cmp)
+    {
+    case EQ_EXPR:
+    case NE_EXPR:
+      /* Check both i-1 and i+1.  */
+      break;
+
+    case LT_EXPR:
+    case GE_EXPR:
+      /* Only check i-1.  */
+      check_ip1 = false;
+      break;
+
+    case LE_EXPR:
+    case GT_EXPR:
+      /* Only check i+1.  */
+      check_im1 = false;
+      break;
+
+    default:
+      return false;
+    }
+
+    if (flag_rounding_math && i != 0)
+      {
+       real_from_integer (&raw, VOIDmode, i, isign);
+       if (!real_identical (r, &raw))
+         return false;
+      }
+
+    if (check_im1 && wi::gt_p (i, lo, isign))
+      {
+       if (flag_rounding_math)
+         {
+           real_from_integer (&raw, VOIDmode, i - 1, isign);
+           real_convert (&rnd, fmt, &raw);
+           if (!real_identical (&raw, &rnd))
+             return false;
+         }
+       else
+         real_from_integer (&rnd, fmt, i - 1, isign);
+       if (real_identical (r, &rnd))
+         return false;
+      }
+
+    if (check_ip1 && wi::lt_p (i, hi, isign))
+      {
+       if (flag_rounding_math)
+         {
+           real_from_integer (&raw, VOIDmode, i + 1, isign);
+           real_convert (&rnd, fmt, &raw);
+           if (!real_identical (&raw, &rnd))
+             return false;
+         }
+       else
+         real_from_integer (&rnd, fmt, i + 1, isign);
+       if (real_identical (r, &rnd))
+         return false;
+      }
+
+  return true;
+}
+
 /* Subroutine of match.pd that optimizes comparisons of a division by
    a nonzero integer constant against an integer constant, i.e.
    X/C1 op C2.
diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index 8c0c3edba17..25e1cbf911f 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -173,6 +173,12 @@ extern bool integer_valued_real_p (tree, int = 0);
 
 extern bool fold_real_zero_addition_p (const_tree, const_tree, const_tree,
                                       int);
+extern bool fold_cmp_float_cst_p (wide_int lo, wide_int hi,
+                                 enum tree_code cmp,
+                                 const REAL_VALUE_TYPE *r,
+                                 format_helper fmt,
+                                 wide_int i, signop isign);
+
 extern tree combine_comparisons (location_t, enum tree_code, enum tree_code,
                                 enum tree_code, tree, tree, tree);
 extern tree_code combine_comparisons (enum tree_code, enum tree_code,
diff --git a/gcc/match.pd b/gcc/match.pd
index 7da15cc4cdc..91f09532a81 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -7730,6 +7730,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
     (with
      {
        tree itype = TREE_TYPE (@0);
+       signop isign = TYPE_SIGN (itype);
        format_helper fmt (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (@1))));
        bool itype_ok = fmt.can_represent_integral_type_p (itype);
        bool value_ok = itype_ok;
@@ -7747,10 +7748,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
           && gimple_match_range_of_expr (vr, @0, @2))
         value_ok = fmt.can_represent_range_value_p (&vr);
 #endif
+       /* Conversion may raise FPE_INEXACT with -ftrapping-math.  */
+       if (flag_trapping_math && !value_ok)
+        exception_p = true;
      }
-     /* TODO: allow non-fitting itype and SNaNs when
-       -fno-trapping-math.  */
-     (if (value_ok && ! exception_p)
+
+     (if (! exception_p)
       (with
        {
         signop isign = TYPE_SIGN (itype);
@@ -7775,7 +7778,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
         else
           real_trunc (&icst, fmt, cst);
 
-        bool cst_int_p = !real_isnan (cst) && real_identical (&icst, cst);
+        bool cst_int_p = real_isfinite (cst) && real_identical (&icst, cst);
 
         bool overflow_p = false;
         wide_int icst_val
@@ -7789,21 +7792,23 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        (if (real_compare (GT_EXPR, cst, &imax))
         { constant_boolean_node (cmp == LT_EXPR || cmp == LE_EXPR || cmp == 
NE_EXPR,
                                  type); })
-       /* Remove cast if CST is an integer representable by ITYPE.  */
-       (if (cst_int_p)
-        (cmp @0 { gcc_assert (!overflow_p);
-                  wide_int_to_tree (itype, icst_val); })
-       )
-       /* When CST is fractional, optimize
+       /* When CST is fractional, infinity or NaN, then optimize
            (FTYPE) N == CST -> 0
            (FTYPE) N != CST -> 1.  */
-       (if (cmp == EQ_EXPR || cmp == NE_EXPR)
+       (if (!cst_int_p
+            && (cmp == EQ_EXPR || cmp == NE_EXPR))
         { constant_boolean_node (cmp == NE_EXPR, type); })
+       /* Remove cast if CST is an integer representable by ITYPE,
+          and it is safe to do so.  */
+       (if (cst_int_p
+            && fold_cmp_float_cst_p (imin_val, imax_val, cmp, &icst, fmt,
+                                     icst_val, isign))
+        (cmp @0 { wide_int_to_tree (itype, icst_val); })
+       )
        /* Otherwise replace with sensible integer constant.  */
-       (with
-        {
-          gcc_checking_assert (!overflow_p);
-        }
+       (if (!cst_int_p
+            && fold_cmp_float_cst_p (imin_val, imax_val, icmp, &icst, fmt,
+                                     icst_val, isign))
         (icmp @0 { wide_int_to_tree (itype, icst_val); })))))))))
 
 /* Fold A /[ex] B CMP C to A CMP B * C.  */
diff --git a/gcc/testsuite/c-c++-common/pr57371-10.c 
b/gcc/testsuite/c-c++-common/pr57371-10.c
new file mode 100644
index 00000000000..96172767c78
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr57371-10.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -fno-trapping-math -frounding-math" 
} */
+
+int foo1 (int a) {
+  return (float) a != 16777222.0f;
+}
+
+int foo2 (unsigned int b) {
+  return (float) b != 16777222.0f;
+}
+
+int foo3 (unsigned long long c) {
+  return (float) c != 16777222.0f;
+}
+
+int foo4 (long long d) {
+  return (float) d != 16777222.0f;
+}
+
+/* { dg-final { scan-tree-dump-times "\\(float\\)" 4 "optimized" } } */
diff --git a/gcc/testsuite/c-c++-common/pr57371-6.c 
b/gcc/testsuite/c-c++-common/pr57371-6.c
new file mode 100644
index 00000000000..3486b94bac8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr57371-6.c
@@ -0,0 +1,200 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -fno-trapping-math" } */
+
+int foo1 (int p) {
+  return (float) p != 0;
+  /* { dg-final { scan-tree-dump "p_\[0-9]\\(D\\) != 0;" "optimized" } } */
+}
+
+int foo2 (unsigned int q) {
+  return (float) q != 0;
+  /* { dg-final { scan-tree-dump "q_\[0-9]\\(D\\) != 0;" "optimized" } } */
+}
+
+int foo3 (long long r) {
+  return (float) r != 0;
+  /* { dg-final { scan-tree-dump "r_\[0-9]\\(D\\) != 0;" "optimized" } } */
+}
+
+int foo4 (unsigned long long s) {
+  return (float) s != 0;
+  /* { dg-final { scan-tree-dump "s_\[0-9]\\(D\\) != 0;" "optimized" } } */
+}
+
+int foo5 (long long t) {
+  return (double) t != 0;
+  /* { dg-final { scan-tree-dump "t_\[0-9]\\(D\\) != 0;" "optimized" } } */
+}
+
+int foo6 (unsigned long long u) {
+  return (double) u != 0;
+  /* { dg-final { scan-tree-dump "u_\[0-9]\\(D\\) != 0;" "optimized" } } */
+}
+
+/* Tests when RHS is within range of integer type.  */
+
+void in_range (unsigned int x)
+{
+  {
+    volatile int in_range_1;
+    in_range_1 = (float) x > 100.0f;
+    /* { dg-final { scan-tree-dump " > 100;" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_2;
+    in_range_2 = (float) x < 200.0f;
+    /* { dg-final { scan-tree-dump " <= 199;" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_3;
+    in_range_3 = (float) x > 300.5f;
+    /* { dg-final { scan-tree-dump " > 300;" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_4;
+    in_range_4 = (float) x < 400.5f;
+    /* { dg-final { scan-tree-dump " <= 400;" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_5;
+    in_range_5 = (float) x == 500.0f;
+    /* { dg-final { scan-tree-dump " == 500;" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_6;
+    in_range_6 = (float) x != 600.0f;
+    /* { dg-final { scan-tree-dump " != 600;" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_7;
+    in_range_7 = (float) x == 700.5f;
+    /* { dg-final { scan-tree-dump "in_range_7 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_8;
+    in_range_8 = (float) x != 800.5f;
+    /* { dg-final { scan-tree-dump "in_range_8 ={v} 1" "optimized" } } */
+  }
+}
+
+/* Tests for cases where RHS is out of range of integer type.  */
+
+void out_range (unsigned int x)
+{
+  {
+    volatile int out_range_1;
+    out_range_1 = (float) x > -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_1 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int out_range_2;
+    out_range_2 = (float) x >= -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_2 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int out_range_3;
+    out_range_3 = (float) x < -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_3 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int out_range_4;
+    out_range_4 = (float) x <= -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_4 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int out_range_5;
+    out_range_5 = (float) x == -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_5 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int out_range_6;
+    out_range_6 = (float) x != -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_6 ={v} 1" "optimized" } } */
+  }
+}
+
+/* Tests with non-finite float consts.  */
+
+void nonfinite (unsigned int x)
+{
+#define INFINITY __builtin_inff ()
+
+  {
+    volatile int nonfinite_1;
+    nonfinite_1 = (float) x > INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_1 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_2;
+    nonfinite_2 = (float) x >= INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_2 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_3;
+    nonfinite_3 = (float) x < INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_3 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_4;
+    nonfinite_4 = (float) x <= INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_4 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_5;
+    nonfinite_5 = (float) x > -INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_5 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_6;
+    nonfinite_6 = (float) x >= -INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_6 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_7;
+    nonfinite_7 = (float) x < -INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_7 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_8;
+    nonfinite_8 = (float) x <= -INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_8 ={v} 0" "optimized" } } */
+  }
+
+#define QNAN __builtin_nanf ("0")
+
+  /* Even for qNaNs, only == and != are quiet.  */
+
+  {
+    volatile int nonfinite_9;
+    nonfinite_9 = (float) x == QNAN;
+    /* { dg-final { scan-tree-dump "nonfinite_9 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_10;
+    nonfinite_10 = (float) x != QNAN;
+    /* { dg-final { scan-tree-dump "nonfinite_10 ={v} 1" "optimized" } } */
+  }
+}
+
+/* { dg-final { scan-tree-dump-not "\\(float\\)" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "\\(double\\)" "optimized" } } */
diff --git a/gcc/testsuite/c-c++-common/pr57371-7.c 
b/gcc/testsuite/c-c++-common/pr57371-7.c
new file mode 100644
index 00000000000..b976eb9b17e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr57371-7.c
@@ -0,0 +1,218 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo1 (int a) {
+  a &= 4095;
+  return (float) a != 0.0f;
+  /* { dg-final { scan-tree-dump "a_\[0-9] != 0;" "optimized" } } */
+}
+
+int foo2 (unsigned int b) {
+  b &= 4095;
+  return (float) b != 0.0f;
+  /* { dg-final { scan-tree-dump "b_\[0-9] != 0;" "optimized" } } */
+}
+
+int foo3 (unsigned long long c) {
+  c &= 4095;
+  return (float) c != 0.0f;
+  /* { dg-final { scan-tree-dump "c_\[0-9] != 0;" "optimized" } } */
+}
+
+int foo4 (long long d) {
+  d &= 4095;
+  return (float) d != 0.0f;
+  /* { dg-final { scan-tree-dump "d_\[0-9] != 0;" "optimized" } } */
+}
+
+/* Tests when RHS is within range of integer type.  */
+
+void in_range (unsigned int x)
+{
+  {
+    volatile int in_range_1;
+    x &= 4095;
+    in_range_1 = (float) x > 100.0f;
+    /* { dg-final { scan-tree-dump " > 100" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_2;
+    x &= 4095;
+    in_range_2 = (float) x < 200.0f;
+    /* { dg-final { scan-tree-dump " <= 199" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_3;
+    x &= 4095;
+    in_range_3 = (float) x > 300.5f;
+    /* { dg-final { scan-tree-dump " > 300" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_4;
+    x &= 4095;
+    in_range_4 = (float) x < 400.5f;
+    /* { dg-final { scan-tree-dump " <= 400" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_5;
+    x &= 4095;
+    in_range_5 = (float) x == 500.0f;
+    /* { dg-final { scan-tree-dump " == 500" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_6;
+    x &= 4095;
+    in_range_6 = (float) x != 600.0f;
+    /* { dg-final { scan-tree-dump " != 600" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_7;
+    x &= 4095;
+    in_range_7 = (float) x == 700.5f;
+    /* { dg-final { scan-tree-dump "in_range_7 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int in_range_8;
+    x &= 4095;
+    in_range_8 = (float) x != 800.5f;
+    /* { dg-final { scan-tree-dump "in_range_8 ={v} 1" "optimized" } } */
+  }
+}
+
+/* Tests for cases where RHS is out of range of integer type.  */
+
+void out_range (unsigned int x)
+{
+  {
+    volatile int out_range_1;
+    x &= 4095;
+    out_range_1 = (float) x > -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_1 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int out_range_2;
+    x &= 4095;
+    out_range_2 = (float) x >= -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_2 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int out_range_3;
+    x &= 4095;
+    out_range_3 = (float) x < -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_3 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int out_range_4;
+    x &= 4095;
+    out_range_4 = (float) x <= -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_4 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int out_range_5;
+    x &= 4095;
+    out_range_5 = (float) x == -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_5 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int out_range_6;
+    x &= 4095;
+    out_range_6 = (float) x != -100.5f;
+    /* { dg-final { scan-tree-dump "out_range_6 ={v} 1" "optimized" } } */
+  }
+}
+
+/* Tests with non-finite float consts.  */
+
+void nonfinite (unsigned int x)
+{
+#define INFINITY __builtin_inff ()
+
+  {
+    volatile int nonfinite_1;
+    x &= 4095;
+    nonfinite_1 = (float) x > INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_1 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_2;
+    x &= 4095;
+    nonfinite_2 = (float) x >= INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_2 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_3;
+    x &= 4095;
+    nonfinite_3 = (float) x < INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_3 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_4;
+    x &= 4095;
+    nonfinite_4 = (float) x <= INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_4 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_5;
+    x &= 4095;
+    nonfinite_5 = (float) x > -INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_5 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_6;
+    x &= 4095;
+    nonfinite_6 = (float) x >= -INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_6 ={v} 1" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_7;
+    x &= 4095;
+    nonfinite_7 = (float) x < -INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_7 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_8;
+    x &= 4095;
+    nonfinite_8 = (float) x <= -INFINITY;
+    /* { dg-final { scan-tree-dump "nonfinite_8 ={v} 0" "optimized" } } */
+  }
+
+#define QNAN __builtin_nanf ("0")
+
+  /* Even for qNaNs, only == and != are quiet.  */
+
+  {
+    volatile int nonfinite_9;
+    x &= 4095;
+    nonfinite_9 = (float) x == QNAN;
+    /* { dg-final { scan-tree-dump "nonfinite_9 ={v} 0" "optimized" } } */
+  }
+
+  {
+    volatile int nonfinite_10;
+    x &= 4095;
+    nonfinite_10 = (float) x != QNAN;
+    /* { dg-final { scan-tree-dump "nonfinite_10 ={v} 1" "optimized" } } */
+  }
+}
+
+/* { dg-final { scan-tree-dump-not "\\(float\\)" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "\\(double\\)" "optimized" } } */
diff --git a/gcc/testsuite/c-c++-common/pr57371-8.c 
b/gcc/testsuite/c-c++-common/pr57371-8.c
new file mode 100644
index 00000000000..d0d7eecc9a1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr57371-8.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -fno-trapping-math" } */
+
+int foo1 (int a) {
+  return (float) a != 16777220.0f;
+}
+
+int foo2 (unsigned int b) {
+  return (float) b != 16777220.0f;
+}
+
+int foo3 (unsigned long long c) {
+  return (float) c != 16777220.0f;
+}
+
+int foo4 (long long d) {
+  return (float) d != 16777220.0f;
+}
+
+/* { dg-final { scan-tree-dump-times "\\(float\\)" 4 "optimized" } } */
diff --git a/gcc/testsuite/c-c++-common/pr57371-9.c 
b/gcc/testsuite/c-c++-common/pr57371-9.c
new file mode 100644
index 00000000000..32b8cbadfb1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr57371-9.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -fno-trapping-math" } */
+
+int foo1 (int a) {
+  return (float) a != 16777222.0f;
+  /* { dg-final { scan-tree-dump "a_\[0-9]\\(D\\) != 16777222;" "optimized" } 
} */
+}
+
+int foo2 (unsigned int b) {
+  return (float) b != 16777222.0f;
+  /* { dg-final { scan-tree-dump "b_\[0-9]\\(D\\) != 16777222;" "optimized" } 
} */
+}
+
+int foo3 (unsigned long long c) {
+  return (float) c != 16777222.0f;
+  /* { dg-final { scan-tree-dump "c_\[0-9]\\(D\\) != 16777222;" "optimized" } 
} */
+}
+
+int foo4 (long long d) {
+  return (float) d != 16777222.0f;
+  /* { dg-final { scan-tree-dump "d_\[0-9]\\(D\\) != 16777222;" "optimized" } 
} */
+}
+
+/* { dg-final { scan-tree-dump-not "\\(float\\)" "optimized" } } */

Reply via email to