Commit 32c8bce7 by Duncan Sands Committed by Duncan Sands

re PR tree-optimization/23744 (VRP does not merge discontinuous ranges of PHIs)

	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.

From-SVN: r119320
parent 7f9faf5e
2006-11-29 Duncan Sands <baldrick@free.fr>
PR tree-optimization/23744
* tree-vrp.c (vrp_meet): do not require ranges to intersect.
2006-11-29 Duncan Sands <baldrick@free.fr>
PR tree-optimization/23744
* testsuite/gcc.dg/tree-ssa/pr23744.c: new test.
2006-11-29 Duncan Sands <baldrick@free.fr>
PR tree-optimization/23744
* testsuite/gcc.dg/tree-ssa/update-threading.c: xfail.
2006-11-29 Jie Zhang <jie.zhang@analog.com> 2006-11-29 Jie Zhang <jie.zhang@analog.com>
* doc/tm.texi (NO_PROFILE_COUNTERS): Document more accurately. * doc/tm.texi (NO_PROFILE_COUNTERS): Document more accurately.
......
/* { 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" } } */
...@@ -20,5 +20,5 @@ main (int argc, char **argv) ...@@ -20,5 +20,5 @@ main (int argc, char **argv)
foo (((A) { ((!(i >> 4) ? 8 : 64 + (i >> 4)) << 8) + (i << 4) } ).a); foo (((A) { ((!(i >> 4) ? 8 : 64 + (i >> 4)) << 8) + (i << 4) } ).a);
exit (0); 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" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
...@@ -3978,14 +3978,8 @@ vrp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p) ...@@ -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 /* Meet operation for value ranges. Given two value ranges VR0 and
VR1, store in VR0 the result of meeting VR0 and VR1. VR1, store in VR0 a range that contains both VR0 and VR1. This
may not be the smallest possible such range. */
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. */
static void static void
vrp_meet (value_range_t *vr0, value_range_t *vr1) vrp_meet (value_range_t *vr0, value_range_t *vr1)
...@@ -4016,40 +4010,30 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1) ...@@ -4016,40 +4010,30 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
if (vr0->type == VR_RANGE && vr1->type == VR_RANGE) 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; int cmp;
tree min, max; tree min, max;
/* The lower limit of the new range is the minimum of the /* Compute the convex hull of the ranges. The lower limit of
two ranges. If they cannot be compared, the result is the new range is the minimum of the two ranges. If they
VARYING. */ cannot be compared, then give up. */
cmp = compare_values (vr0->min, vr1->min); cmp = compare_values (vr0->min, vr1->min);
if (cmp == 0 || cmp == 1) if (cmp == 0 || cmp == 1)
min = vr1->min; min = vr1->min;
else if (cmp == -1) else if (cmp == -1)
min = vr0->min; min = vr0->min;
else else
{ goto give_up;
set_value_range_to_varying (vr0);
return;
}
/* Similarly, the upper limit of the new range is the /* Similarly, the upper limit of the new range is the maximum
maximum of the two ranges. If they cannot be compared, of the two ranges. If they cannot be compared, then
the result is VARYING. */ give up. */
cmp = compare_values (vr0->max, vr1->max); cmp = compare_values (vr0->max, vr1->max);
if (cmp == 0 || cmp == -1) if (cmp == 0 || cmp == -1)
max = vr1->max; max = vr1->max;
else if (cmp == 1) else if (cmp == 1)
max = vr0->max; max = vr0->max;
else else
{ goto give_up;
set_value_range_to_varying (vr0);
return;
}
/* The resulting set of equivalences is the intersection of /* The resulting set of equivalences is the intersection of
the two sets. */ the two sets. */
...@@ -4060,12 +4044,10 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1) ...@@ -4060,12 +4044,10 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
set_value_range (vr0, vr0->type, min, max, vr0->equiv); set_value_range (vr0, vr0->type, min, max, vr0->equiv);
} }
else
goto no_meet;
}
else if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE) 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 if (compare_values (vr0->min, vr1->min) == 0
&& compare_values (vr0->max, vr1->max) == 0 && compare_values (vr0->max, vr1->max) == 0
&& compare_values (vr0->min, vr0->max) == 0) && compare_values (vr0->min, vr0->max) == 0)
...@@ -4078,13 +4060,13 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1) ...@@ -4078,13 +4060,13 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
bitmap_clear (vr0->equiv); bitmap_clear (vr0->equiv);
} }
else else
goto no_meet; goto give_up;
} }
else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE) else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
{ {
/* A numeric range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4] /* For a numeric range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4],
meet only if the ranges have an empty intersection. The only handle the case where the ranges have an empty intersection.
result of the meet operation is the anti-range. */ The result of the meet operation is the anti-range. */
if (!symbolic_range_p (vr0) if (!symbolic_range_p (vr0)
&& !symbolic_range_p (vr1) && !symbolic_range_p (vr1)
&& !value_ranges_intersect_p (vr0, vr1)) && !value_ranges_intersect_p (vr0, vr1))
...@@ -4103,17 +4085,17 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1) ...@@ -4103,17 +4085,17 @@ vrp_meet (value_range_t *vr0, value_range_t *vr1)
bitmap_clear (vr0->equiv); bitmap_clear (vr0->equiv);
} }
else else
goto no_meet; goto give_up;
} }
else else
gcc_unreachable (); gcc_unreachable ();
return; return;
no_meet: give_up:
/* The two range VR0 and VR1 do not meet. Before giving up and /* Failed to find an efficient meet. Before giving up and setting
setting the result to VARYING, see if we can at least derive a the result to VARYING, see if we can at least derive a useful
useful anti-range. FIXME, all this nonsense about distinguishing anti-range. FIXME, all this nonsense about distinguishing
anti-ranges from ranges is necessary because of the odd anti-ranges from ranges is necessary because of the odd
semantics of range_includes_zero_p and friends. */ semantics of range_includes_zero_p and friends. */
if (!symbolic_range_p (vr0) if (!symbolic_range_p (vr0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment