On Thu, May 24, 2012 at 1:41 PM, Jakub Jelinek <ja...@redhat.com> wrote: > 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?
Ok. Thanks, Richard. > 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