diff mbox series

VRP: normalize VR_VARYING in PLUS/MINUS_EXPR handling

Message ID d5cea256-62d2-3576-480e-6902e378861a@redhat.com
State New
Headers show
Series VRP: normalize VR_VARYING in PLUS/MINUS_EXPR handling | expand

Commit Message

Aldy Hernandez Sept. 11, 2018, 10:34 a.m. UTC
For addition and subtraction, we're currently punting on things like 
[0,0] - VR_VARYING.  However, if we normalize VR_VARYING to the entire 
domain, we can see that the above is actually [-MIN+1, +MAX].

We would've normally caught this sort of things with my rewrite of the 
binary operators, but PLUS/MINUS are special in that they're pretty much 
the only operator that keeps symbolics through it's calculations.  This 
is why we can't just blindly treat symbolics as [-MIN, +MAX] as I've 
done elsewhere.  PLUS/MINUS are handled specially (ugly) :-/.

OK for trunk?

Comments

Richard Biener Sept. 14, 2018, 7:14 a.m. UTC | #1
On Tue, Sep 11, 2018 at 12:34 PM Aldy Hernandez <aldyh@redhat.com> wrote:
>
> For addition and subtraction, we're currently punting on things like
> [0,0] - VR_VARYING.  However, if we normalize VR_VARYING to the entire
> domain, we can see that the above is actually [-MIN+1, +MAX].
>
> We would've normally caught this sort of things with my rewrite of the
> binary operators, but PLUS/MINUS are special in that they're pretty much
> the only operator that keeps symbolics through it's calculations.  This
> is why we can't just blindly treat symbolics as [-MIN, +MAX] as I've
> done elsewhere.  PLUS/MINUS are handled specially (ugly) :-/.
>
> OK for trunk?

OK.

>
diff mbox series

Patch

gcc/

	* tree-vrp.c (extract_range_from_binary_expr_1): Normalize
	VR_VARYING for PLUS/MINUS_EXPR.

diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 8f16713300c..27ef96c27e7 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1426,6 +1426,22 @@  extract_range_from_binary_expr_1 (value_range *vr,
      range and see what we end up with.  */
   if (code == PLUS_EXPR || code == MINUS_EXPR)
     {
+      /* This will normalize things such that calculating
+	 [0,0] - VR_VARYING is not dropped to varying, but is
+	 calculated as [MIN+1, MAX].  */
+      if (vr0.type == VR_VARYING)
+	{
+	  vr0.type = VR_RANGE;
+	  vr0.min = vrp_val_min (expr_type);
+	  vr0.max = vrp_val_max (expr_type);
+	}
+      if (vr1.type == VR_VARYING)
+	{
+	  vr1.type = VR_RANGE;
+	  vr1.min = vrp_val_min (expr_type);
+	  vr1.max = vrp_val_max (expr_type);
+	}
+
       const bool minus_p = (code == MINUS_EXPR);
       tree min_op0 = vr0.min;
       tree min_op1 = minus_p ? vr1.max : vr1.min;