aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorKazu Hirata <kazu@codesourcery.com>2005-06-26 03:49:20 +0000
committerKazu Hirata <kazu@codesourcery.com>2005-06-26 03:49:20 +0000
commita518aae64998742742ff4f41902c898e430543b3 (patch)
tree46e58ccdccdc24fd647e7fd019278bafcdc726f2 /gcc/tree-vrp.c
parentfa5ab386f100d459f3bd5428a4347cc3bfe94cbb (diff)
gcc/
PR tree-optimization/22026 * tree-vrp.c (extract_range_from_binary_expr): Drop to VR_VARYING if a binary expression involving VR_ANTI_RANGE is PLUS_EXPR, MINUS_EXPR, or unsigned MULT_EXPR. testsuite/ PR tree-optimization/22026 * gcc.dg/tree-ssa/pr22026.c: New. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@101328 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 37bcb1b26c9..e733a8de7b9 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1107,6 +1107,19 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
|| code == MIN_EXPR
|| code == MAX_EXPR)
{
+ /* If we have a PLUS_EXPR with two VR_ANTI_RANGEs, drop to
+ VR_VARYING. It would take more effort to compute a precise
+ range for such a case. For example, if we have op0 == 1 and
+ op1 == -1 with their ranges both being ~[0,0], we would have
+ op0 + op1 == 0, so we cannot claim that the sum is in ~[0,0].
+ Note that we are guaranteed to have vr0.type == vr1.type at
+ this point. */
+ if (code == PLUS_EXPR && vr0.type == VR_ANTI_RANGE)
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
+
/* For operations that make the resulting range directly
proportional to the original ranges, apply the operation to
the same end of each range. */
@@ -1123,6 +1136,22 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
tree val[4];
size_t i;
+ /* If we have an unsigned MULT_EXPR with two VR_ANTI_RANGEs,
+ drop to VR_VARYING. It would take more effort to compute a
+ precise range for such a case. For example, if we have
+ op0 == 65536 and op1 == 65536 with their ranges both being
+ ~[0,0] on a 32-bit machine, we would have op0 * op1 == 0, so
+ we cannot claim that the product is in ~[0,0]. Note that we
+ are guaranteed to have vr0.type == vr1.type at this
+ point. */
+ if (code == MULT_EXPR
+ && vr0.type == VR_ANTI_RANGE
+ && (flag_wrapv || TYPE_UNSIGNED (TREE_TYPE (op0))))
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
+
/* Multiplications and divisions are a bit tricky to handle,
depending on the mix of signs we have in the two ranges, we
need to operate on different values to get the minimum and
@@ -1188,6 +1217,19 @@ extract_range_from_binary_expr (value_range_t *vr, tree expr)
}
else if (code == MINUS_EXPR)
{
+ /* If we have a MINUS_EXPR with two VR_ANTI_RANGEs, drop to
+ VR_VARYING. It would take more effort to compute a precise
+ range for such a case. For example, if we have op0 == 1 and
+ op1 == 1 with their ranges both being ~[0,0], we would have
+ op0 - op1 == 0, so we cannot claim that the difference is in
+ ~[0,0]. Note that we are guaranteed to have
+ vr0.type == vr1.type at this point. */
+ if (vr0.type == VR_ANTI_RANGE)
+ {
+ set_value_range_to_varying (vr);
+ return;
+ }
+
/* For MINUS_EXPR, apply the operation to the opposite ends of
each range. */
min = vrp_int_const_binop (code, vr0.min, vr1.max);