summaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorbaldrick <baldrick@138bc75d-0d04-0410-961f-82ee72b054a4>2006-11-29 16:00:07 +0000
committerbaldrick <baldrick@138bc75d-0d04-0410-961f-82ee72b054a4>2006-11-29 16:00:07 +0000
commitab37e731f0b09acd65260c447c4cf17c419ed2b0 (patch)
tree79077c165b5fa64d656ddc1ba77c96e3ccb5d22b /gcc/tree-vrp.c
parent1a9b4c25c61b2f6fa52c4944055003f6fba889fc (diff)
downloadgcc-ab37e731f0b09acd65260c447c4cf17c419ed2b0.tar.gz
PR tree-optimization/23744
* tree-vrp.c (vrp_meet): do not require ranges to intersect. * testsuite/gcc.dg/tree-ssa/pr23744.c: new test. * testsuite/gcc.dg/tree-ssa/update-threading.c: xfail. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119320 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c106
1 files changed, 44 insertions, 62 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index fed86cbc5e6..b55480ee8cd 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3978,14 +3978,8 @@ vrp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
/* Meet operation for value ranges. Given two value ranges VR0 and
- VR1, store in VR0 the result of meeting VR0 and VR1.
-
- The meeting rules are as follows:
-
- 1- If VR0 and VR1 have an empty intersection, set VR0 to VR_VARYING.
-
- 2- If VR0 and VR1 have a non-empty intersection, set VR0 to the
- union of VR0 and VR1. */
+ VR1, store in VR0 a range that contains both VR0 and VR1. This
+ may not be the smallest possible such range. */
static void
vrp_meet (value_range_t *vr0, value_range_t *vr1)
@@ -4016,56 +4010,44 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
if (vr0->type == VR_RANGE && vr1->type == VR_RANGE)
{
- /* If VR0 and VR1 have a non-empty intersection, compute the
- union of both ranges. */
- if (value_ranges_intersect_p (vr0, vr1))
- {
- int cmp;
- tree min, max;
-
- /* The lower limit of the new range is the minimum of the
- two ranges. If they cannot be compared, the result is
- VARYING. */
- cmp = compare_values (vr0->min, vr1->min);
- if (cmp == 0 || cmp == 1)
- min = vr1->min;
- else if (cmp == -1)
- min = vr0->min;
- else
- {
- set_value_range_to_varying (vr0);
- return;
- }
-
- /* Similarly, the upper limit of the new range is the
- maximum of the two ranges. If they cannot be compared,
- the result is VARYING. */
- cmp = compare_values (vr0->max, vr1->max);
- if (cmp == 0 || cmp == -1)
- max = vr1->max;
- else if (cmp == 1)
- max = vr0->max;
- else
- {
- set_value_range_to_varying (vr0);
- return;
- }
+ int cmp;
+ tree min, max;
+
+ /* Compute the convex hull of the ranges. The lower limit of
+ the new range is the minimum of the two ranges. If they
+ cannot be compared, then give up. */
+ cmp = compare_values (vr0->min, vr1->min);
+ if (cmp == 0 || cmp == 1)
+ min = vr1->min;
+ else if (cmp == -1)
+ min = vr0->min;
+ else
+ goto give_up;
+
+ /* Similarly, the upper limit of the new range is the maximum
+ of the two ranges. If they cannot be compared, then
+ give up. */
+ cmp = compare_values (vr0->max, vr1->max);
+ if (cmp == 0 || cmp == -1)
+ max = vr1->max;
+ else if (cmp == 1)
+ max = vr0->max;
+ else
+ goto give_up;
- /* The resulting set of equivalences is the intersection of
- the two sets. */
- if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
- bitmap_and_into (vr0->equiv, vr1->equiv);
- else if (vr0->equiv && !vr1->equiv)
- bitmap_clear (vr0->equiv);
+ /* The resulting set of equivalences is the intersection of
+ the two sets. */
+ if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
+ bitmap_and_into (vr0->equiv, vr1->equiv);
+ else if (vr0->equiv && !vr1->equiv)
+ bitmap_clear (vr0->equiv);
- set_value_range (vr0, vr0->type, min, max, vr0->equiv);
- }
- else
- goto no_meet;
+ set_value_range (vr0, vr0->type, min, max, vr0->equiv);
}
else if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
{
- /* Two anti-ranges meet only if they are both identical. */
+ /* Two anti-ranges meet only if their complements intersect.
+ Only handle the case of identical ranges. */
if (compare_values (vr0->min, vr1->min) == 0
&& compare_values (vr0->max, vr1->max) == 0
&& compare_values (vr0->min, vr0->max) == 0)
@@ -4078,13 +4060,13 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
bitmap_clear (vr0->equiv);
}
else
- goto no_meet;
+ goto give_up;
}
else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
{
- /* A numeric range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4]
- meet only if the ranges have an empty intersection. The
- result of the meet operation is the anti-range. */
+ /* For a numeric range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4],
+ only handle the case where the ranges have an empty intersection.
+ The result of the meet operation is the anti-range. */
if (!symbolic_range_p (vr0)
&& !symbolic_range_p (vr1)
&& !value_ranges_intersect_p (vr0, vr1))
@@ -4103,17 +4085,17 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
bitmap_clear (vr0->equiv);
}
else
- goto no_meet;
+ goto give_up;
}
else
gcc_unreachable ();
return;
-no_meet:
- /* The two range VR0 and VR1 do not meet. Before giving up and
- setting the result to VARYING, see if we can at least derive a
- useful anti-range. FIXME, all this nonsense about distinguishing
+give_up:
+ /* Failed to find an efficient meet. Before giving up and setting
+ the result to VARYING, see if we can at least derive a useful
+ anti-range. FIXME, all this nonsense about distinguishing
anti-ranges from ranges is necessary because of the odd
semantics of range_includes_zero_p and friends. */
if (!symbolic_range_p (vr0)