From ab37e731f0b09acd65260c447c4cf17c419ed2b0 Mon Sep 17 00:00:00 2001 From: baldrick Date: Wed, 29 Nov 2006 16:00:07 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 15 ++++ gcc/testsuite/gcc.dg/tree-ssa/pr23744.c | 19 ++++ gcc/testsuite/gcc.dg/tree-ssa/update-threading.c | 2 +- gcc/tree-vrp.c | 106 ++++++++++------------- 4 files changed, 79 insertions(+), 63 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr23744.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 30b8410269a..5bb4362523e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2006-11-29 Duncan Sands + + PR tree-optimization/23744 + * tree-vrp.c (vrp_meet): do not require ranges to intersect. + +2006-11-29 Duncan Sands + + PR tree-optimization/23744 + * testsuite/gcc.dg/tree-ssa/pr23744.c: new test. + +2006-11-29 Duncan Sands + + PR tree-optimization/23744 + * testsuite/gcc.dg/tree-ssa/update-threading.c: xfail. + 2006-11-29 Jie Zhang * doc/tm.texi (NO_PROFILE_COUNTERS): Document more accurately. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c new file mode 100644 index 00000000000..8ba238c745b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23744.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-vrp1" } */ + +int g (int i, int j) +{ + int t = 0; + int i1; + + if (i == j) + t = 3; + for (i1 = 0; i1 < 10000; i1++) h(); + if (t != 5) + return 0; + else + return 1; +} + +/* { dg-final { scan-tree-dump-times "Folding predicate.*to 1" 1 "vrp1" } } */ +/* { dg-final { cleanup-tree-dump "vrp1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/update-threading.c b/gcc/testsuite/gcc.dg/tree-ssa/update-threading.c index e960d3a614d..e0e33b6869a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/update-threading.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/update-threading.c @@ -20,5 +20,5 @@ main (int argc, char **argv) foo (((A) { ((!(i >> 4) ? 8 : 64 + (i >> 4)) << 8) + (i << 4) } ).a); exit (0); } -/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "Invalid sum" 0 "optimized" { xfail *-*-* } } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ 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) -- 2.11.0