diff options
author | baldrick <baldrick@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-11-29 16:00:07 +0000 |
---|---|---|
committer | baldrick <baldrick@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-11-29 16:00:07 +0000 |
commit | ab37e731f0b09acd65260c447c4cf17c419ed2b0 (patch) | |
tree | 79077c165b5fa64d656ddc1ba77c96e3ccb5d22b /gcc/tree-vrp.c | |
parent | 1a9b4c25c61b2f6fa52c4944055003f6fba889fc (diff) | |
download | gcc-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.c | 106 |
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) |