First, there's no sense handling !VR_RANGE and symbolics now that we've normalized the inputs.

Second, even if we wrap around while calculating ABS, we at the least know the result is positive ;-). BTW, we've already handled ABS(-MIN) and -frapv by the time we get here, so we know we won't get nonsensical input.

OK?
commit 6e874be13a0bd53811e095328c1d175723f11f84
Author: Aldy Hernandez <al...@redhat.com>
Date:   Fri Sep 14 00:03:04 2018 +0200

            * tree-vrp.c (extract_range_from_unary_expr): Do not special case
            symbolics or VR_VARYING ranges for ABS_EXPR.
            * wide-int-range.cc (wide_int_range_abs): Return positive numbers
            when range will wrap.

diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 1adb919a6df..622ccbc2df7 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1894,11 +1894,6 @@ extract_range_from_unary_expr (value_range *vr,
     }
   else if (code == ABS_EXPR)
     {
-      if (vr0.type != VR_RANGE || symbolic_range_p (&vr0))
-	{
-	  set_value_range_to_varying (vr);
-	  return;
-	}
       wide_int wmin, wmax;
       wide_int vr0_min, vr0_max;
       extract_range_into_wide_ints (&vr0, sign, prec, vr0_min, vr0_max);
diff --git a/gcc/wide-int-range.cc b/gcc/wide-int-range.cc
index 8a3dfd25684..a85fe9f9ad7 100644
--- a/gcc/wide-int-range.cc
+++ b/gcc/wide-int-range.cc
@@ -728,10 +728,13 @@ wide_int_range_abs (wide_int &min, wide_int &max,
     }
 
   /* If the new range has its limits swapped around (MIN > MAX), then
-     the operation caused one of them to wrap around, mark the new
-     range VARYING.  */
+     the operation caused one of them to wrap around.  The only thing
+     we know is that the result is positive.  */
   if (wi::gt_p (min, max, sign))
-      return false;
+    {
+      min = wi::zero (prec);
+      max = max_value;
+    }
   return true;
 }
 

Reply via email to