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?
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;