On 9/15/20 11:57 AM, Aldy Hernandez wrote:
This fixes an ICE when trying to copy a legacy value_range containing a symbolic to a multi-range:

    min = make_ssa_name (type);
    max = build_int_cst (type, 55);
    value_range vv (min, max);
    int_range<2> vr = vv;

This doesn't affect anything currently, as we don't have a lot of interactions between value_range's and multi_range's in trunk right, but it will become a problem as soon as someone tries to get a range from evrp and copy it over to a multi-range.

OK pending tests?

gcc/ChangeLog:

    * range-op.cc (multi_precision_range_tests): Normalize symbolics when copying to a multi-range.
    * value-range.cc (irange::copy_legacy_range): Add test.
---
 gcc/range-op.cc    |  9 +++++++++
 gcc/value-range.cc | 12 +++++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index c5f511422f4..8e52d5318e9 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -3463,6 +3463,15 @@ multi_precision_range_tests ()
   small = big;
   ASSERT_TRUE (small == int_range<1> (INT (21), INT (21), VR_ANTI_RANGE));

+  // Copying a legacy symbolic to an int_range should normalize the
+  // symbolic at copy time.
+  {
+    value_range legacy_range (make_ssa_name (integer_type_node), INT (25));
+    int_range<2> copy = legacy_range;
+    ASSERT_TRUE (copy == int_range<2>  (vrp_val_min (integer_type_node),
+                    INT (25)));
+  }
+
   range3_tests ();
 }

diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 20aa4f114c9..26ccd143e5c 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -101,7 +101,17 @@ irange::copy_legacy_range (const irange &src)
        VR_ANTI_RANGE);
     }
   else
-    set (src.min (), src.max (), VR_RANGE);
+    {
+      // If copying legacy to int_range, normalize any symbolics.
+      if (src.legacy_mode_p () && !range_has_numeric_bounds_p (&src))
+    {
+      value_range cst (src);
+      cst.normalize_symbolics ();
+      set (cst.min (), cst.max ());
+      return;
+    }
+      set (src.min (), src.max ());
+    }
 }

 // Swap min/max if they are out of order.  Return TRUE if further
these seems OK, but can't there be anti-ranges with symbolics  too? ie  ~[a_12, a_12]
The code for that just does:

 else if (src.kind () == VR_ANTI_RANGE)
    set (src.min (), src.max (), VR_ANTI_RANGE);

That should just go to varying I guess?

The conversion to legacy anti-range code also seems a little suspect in some cases...

Finally, we theoretically shouldn't be accessing 'min()' and 'max()' fields in a multirange, which also looks like might happen in the final else clause.

I wonder if it might be less complex to simply have 2 routines, like copy_to_legacy()  and copy_from_legacy()  instead of trying to handle then together?  I do find it seems to require more thinking than it should to follow the cases :-)

Andrew

Reply via email to