[gcc r17-3148] [frange] Convert the float to int cast to sub-ranges.

Aldy Hernandez via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:2c3ff1f475d11a5576adf4c72e8bd5b74ce5b060

commit r17-3148-g2c3ff1f475d11a5576adf4c72e8bd5b74ce5b060
Author: Aldy Hernandez <[email protected]>
Date:   Fri Aug 7 09:50:26 2026 +0000

    [frange] Convert the float to int cast to sub-ranges.
    
    Tested on ppc64le Linux.
    
    gcc/ChangeLog:
    
            * range-op-float.cc (operator_cast::fold_range): Convert each
            sub-range and union the results.
            (range_op_float_tests): New test.

Diff:
---
 gcc/range-op-float.cc | 56 +++++++++++++++++++++++++++++++++------------------
 1 file changed, 36 insertions(+), 20 deletions(-)

diff --git a/gcc/range-op-float.cc b/gcc/range-op-float.cc
index 75514c0603ee..156b4f766db9 100644
--- a/gcc/range-op-float.cc
+++ b/gcc/range-op-float.cc
@@ -2991,31 +2991,37 @@ operator_cast::fold_range (irange &r, tree type, const frange &op1,
       r.set_varying (type);
       return true;
     }
-  REAL_VALUE_TYPE lb, ub;
-  real_trunc (&lb, VOIDmode, &op1.lower_bound ());
-  real_trunc (&ub, VOIDmode, &op1.upper_bound ());
   REAL_VALUE_TYPE l, u;
   l = real_value_from_int_cst (NULL_TREE, TYPE_MIN_VALUE (type));
-  if (real_less (&lb, &l))
-    {
-      r.set_varying (type);
-      return true;
-    }
   u = real_value_from_int_cst (NULL_TREE, TYPE_MAX_VALUE (type));
-  if (real_less (&u, &ub))
-    {
-      r.set_varying (type);
-      return true;
-    }
-  bool fail = false;
-  wide_int wlb = real_to_integer (&lb, &fail, TYPE_PRECISION (type));
-  wide_int wub = real_to_integer (&ub, &fail, TYPE_PRECISION (type));
-  if (fail)
+
+  r.set_undefined ();
+  for (unsigned i = 0; i < op1.num_pairs (); ++i)
     {
-      r.set_varying (type);
-      return true;
+      REAL_VALUE_TYPE lb, ub;
+      real_trunc (&lb, VOIDmode, &op1.lower_bound (i));
+      real_trunc (&ub, VOIDmode, &op1.upper_bound (i));
+      if (real_less (&lb, &l))
+	{
+	  r.set_varying (type);
+	  return true;
+	}
+      if (real_less (&u, &ub))
+	{
+	  r.set_varying (type);
+	  return true;
+	}
+      bool fail = false;
+      wide_int wlb = real_to_integer (&lb, &fail, TYPE_PRECISION (type));
+      wide_int wub = real_to_integer (&ub, &fail, TYPE_PRECISION (type));
+      if (fail)
+	{
+	  r.set_varying (type);
+	  return true;
+	}
+      int_range<2> tmp (type, wlb, wub);
+      r.union_ (tmp);
     }
-  r.set (type, wlb, wub);
   return true;
 }
 
@@ -3281,6 +3287,16 @@ range_op_float_tests ()
   r0.clear_nan ();
   range_op_handler (CONVERT_EXPR).fold_range (r, float_type_node, r0, r0);
   ASSERT_EQ (r.num_pairs (), 2);
+
+  // Cast conversion of (int)([1.0,2.0] U [10.0,11.0]) stays two pieces.
+  r0 = frange_float ("1.0", "2.0");
+  r1 = frange_float ("10.0", "11.0");
+  r0.union_ (r1);
+  r0.clear_nan ();
+  int_range<2> ir, ir_op2;
+  range_op_handler (FIX_TRUNC_EXPR).fold_range (ir, integer_type_node,
+						r0, ir_op2);
+  ASSERT_EQ (ir.num_pairs (), 2);
 }
 
 } // namespace selftest
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.