[PATCH] Fix VRP VR_UNDEFINED handling (PR tree-optimization/53465))

Richard Guenther richard.guenther@gmail.com
Thu May 24 11:44:00 GMT 2012


On Thu, May 24, 2012 at 1:41 PM, Jakub Jelinek <jakub@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  <jakub@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



More information about the Gcc-patches mailing list