On Thu, 19 May 2016, Marek Polacek wrote:

> Since Bin's changes to the niter analysis in r231097, we find ourselves in
> a situation where extract_range_from_binary_expr is given [1, od_5] + UINT_MAX
> on type unsigned.  We combine the lower bounds, which is 1 + UINT_MAX = 
> 0(OVF).
> We then combine the upper bounds, because the max_op0 is not a constant, the
> result of that is UINT_MAX.  That results in min overflow -- and an assert is
> unhappy about that.  As suggested in the PR, a safe thing would be to change
> the assert to dropping to varying.
> 
> Bootstrapped/regtested on x86_64-linux, ok for trunk and 6?

Ok if you leave the assert in (there is at least one unhandled case,
min_ovf == 1 && max_ovf == -1).

Alternatively make the code match the comment and drop the
== 0 checks in your added condition.  Which would suggest
to make the else { an else if (asserted condition) and common
the varying case to else { }.

Thanks,
Richard.

> 2016-05-19  Marek Polacek  <pola...@redhat.com>
> 
>       PR tree-optimization/71031
>       * tree-vrp.c (extract_range_from_binary_expr_1): Drop to varying for
>       min overflow or max underflow and remove an assert.
> 
>       * gcc.dg/tree-ssa/vrp100.c: New test.
> 
> diff --git gcc/testsuite/gcc.dg/tree-ssa/vrp100.c 
> gcc/testsuite/gcc.dg/tree-ssa/vrp100.c
> index e69de29..c0fe4b5 100644
> --- gcc/testsuite/gcc.dg/tree-ssa/vrp100.c
> +++ gcc/testsuite/gcc.dg/tree-ssa/vrp100.c
> @@ -0,0 +1,32 @@
> +/* PR tree-optimization/71031 */
> +/* { dg-do compile } */
> +/* { dg-options "-Os" } */
> +
> +int zj;
> +int **yr;
> +
> +void
> +nn (void)
> +{
> +  unsigned int od = 4;
> +
> +  for (;;)
> +    {
> +      int lk;
> +
> +      for (lk = 0; lk < 2; ++lk)
> +        {
> +          static int cm;
> +
> +          zj = 0;
> +          if (od == 0)
> +            return;
> +          ++od;
> +          for (cm = 0; cm < 2; ++cm)
> +            {
> +              --od;
> +              **yr = 0;
> +            }
> +        }
> +    }
> +}
> diff --git gcc/tree-vrp.c gcc/tree-vrp.c
> index 69e6248..791d738 100644
> --- gcc/tree-vrp.c
> +++ gcc/tree-vrp.c
> @@ -2525,14 +2525,19 @@ extract_range_from_binary_expr_1 (value_range *vr,
>                 set_value_range_to_varying (vr);
>                 return;
>               }
> +           else if ((min_ovf == 1 && max_ovf == 0)
> +                    || (min_ovf == 0 && max_ovf == -1))
> +             {
> +               /* Min overflow or max underflow, drop to VR_VARYING.  */
> +               set_value_range_to_varying (vr);
> +               return;
> +             }
>             else
>               {
>                 /* Min underflow or max overflow.  The range kind
>                    changes to VR_ANTI_RANGE.  */
>                 bool covers = false;
>                 wide_int tem = tmin;
> -               gcc_assert ((min_ovf == -1 && max_ovf == 0)
> -                           || (max_ovf == 1 && min_ovf == 0));
>                 type = VR_ANTI_RANGE;
>                 tmin = tmax + 1;
>                 if (wi::cmp (tmin, tmax, sgn) < 0)
> 
>       Marek
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to