Hi! As discussed in the PR and on IRC, when UNDEFINED meets some vr with equivalences in it, we need to drop the equivalences, at least when the equivalenced SSA_NAME definition doesn't dominate the PHI stmt. The change in vrp_visit_phi_node is needed because otherwise vrp_meet would drop the equivalences even when it should not. The extract_range_from_cond_expr change is because when vrp_meet is called first, we might remove some equivalences even from the original SSA_NAME's vr.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.7? 2012-05-24 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/53465 * tree-vrp.c (extract_range_from_cond_expr): First copy_value_range vr0 into *vr, then vrp_meet that. (vrp_meet): If one vr type is VR_UNDEFINED, ensure the result doesn't have any equivalences. (vrp_visit_phi_node): Call copy_value_range instead of vrp_meet the first time. * gcc.c-torture/execute/pr53465.c: New test. --- gcc/tree-vrp.c.jj 2012-05-17 08:40:45.000000000 +0200 +++ gcc/tree-vrp.c 2012-05-24 10:36:50.433325234 +0200 @@ -3282,8 +3282,8 @@ extract_range_from_cond_expr (value_rang set_value_range_to_varying (&vr1); /* The resulting value range is the union of the operand ranges */ - vrp_meet (&vr0, &vr1); copy_value_range (vr, &vr0); + vrp_meet (vr, &vr1); } @@ -6888,13 +6888,17 @@ vrp_meet (value_range_t *vr0, value_rang { if (vr0->type == VR_UNDEFINED) { - copy_value_range (vr0, vr1); + /* Drop equivalences. See PR53465. */ + set_value_range (vr0, vr1->type, vr1->min, vr1->max, NULL); return; } if (vr1->type == VR_UNDEFINED) { - /* Nothing to do. VR0 already has the resulting range. */ + /* VR0 already has the resulting range, just drop equivalences. + See PR53465. */ + if (vr0->equiv) + bitmap_clear (vr0->equiv); return; } @@ -7036,6 +7040,7 @@ vrp_visit_phi_node (gimple phi) tree lhs = PHI_RESULT (phi); value_range_t *lhs_vr = get_value_range (lhs); value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }; + bool first = true; int edges, old_edges; struct loop *l; @@ -7092,7 +7097,11 @@ vrp_visit_phi_node (gimple phi) fprintf (dump_file, "\n"); } - vrp_meet (&vr_result, &vr_arg); + if (first) + copy_value_range (&vr_result, &vr_arg); + else + vrp_meet (&vr_result, &vr_arg); + first = false; if (vr_result.type == VR_VARYING) break; --- gcc/testsuite/gcc.c-torture/execute/pr53465.c.jj 2012-05-24 10:34:16.867240005 +0200 +++ gcc/testsuite/gcc.c-torture/execute/pr53465.c 2012-05-24 10:33:28.000000000 +0200 @@ -0,0 +1,30 @@ +/* PR tree-optimization/53465 */ + +extern void abort (); + +static const int a[] = { 1, 2 }; + +void +foo (const int *x, int y) +{ + int i; + int b = 0; + int c; + for (i = 0; i < y; i++) + { + int d = x[i]; + if (d == 0) + break; + if (b && d <= c) + abort (); + c = d; + b = 1; + } +} + +int +main () +{ + foo (a, 2); + return 0; +} Jakub