[PATCH] [frange] Convert the float to int cast to sub-ranges.

Aldy Hernandez <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>
Tested on ppc64le Linux.

Pushed.

gcc/ChangeLog:

	* range-op-float.cc (operator_cast::fold_range): Convert each
	sub-range and union the results.
	(range_op_float_tests): New test.
---
 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 75514c0603e..156b4f766db 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
-- 
2.47.3
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.