On Tue, 11 Dec 2012, Jakub Jelinek wrote:

> Hi!
> 
> The following testcase on x86_64 (or the f90-intrinsic-bitsize.f on 32-bit
> HWI) with -Os shows a bug in discover_iteration_bound_by_body_walk.  If some
> bound is a -1, -1 HWI, then adding double_int_one to it overflows into 0, 0
> HWI and we can return that as maximum number of iterations.  We need to
> ignore such bounds instead.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok.

Thanks,
Richard.

> 2012-12-11  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR fortran/55633
>       * tree-ssa-loop-niter.c (discover_iteration_bound_by_body_walk):
>       Ignore bounds on which bound += double_int_one overflowed.
> 
>       * gcc.dg/torture/pr55633.c: New test.
> 
> --- gcc/tree-ssa-loop-niter.c.jj      2012-11-21 16:00:09.000000000 +0100
> +++ gcc/tree-ssa-loop-niter.c 2012-12-11 10:56:49.890396498 +0100
> @@ -3011,7 +3011,12 @@ discover_iteration_bound_by_body_walk (s
>        /* Exit terminates loop at given iteration, while non-exits produce 
> undefined
>        effect on the next iteration.  */
>        if (!elt->is_exit)
> -     bound += double_int_one;
> +     {
> +       bound += double_int_one;
> +       /* If an overflow occurred, ignore the result.  */
> +       if (bound.is_zero ())
> +         continue;
> +     }
>  
>        if (!loop->any_upper_bound
>         || bound.ult (loop->nb_iterations_upper_bound))
> @@ -3037,7 +3042,12 @@ discover_iteration_bound_by_body_walk (s
>      {
>        double_int bound = elt->bound;
>        if (!elt->is_exit)
> -     bound += double_int_one;
> +     {
> +       bound += double_int_one;
> +       /* If an overflow occurred, ignore the result.  */
> +       if (bound.is_zero ())
> +         continue;
> +     }
>  
>        if (!loop->any_upper_bound
>         || bound.ult (loop->nb_iterations_upper_bound))
> --- gcc/testsuite/gcc.dg/torture/pr55633.c.jj 2012-12-11 11:12:19.567069030 
> +0100
> +++ gcc/testsuite/gcc.dg/torture/pr55633.c    2012-12-11 11:12:04.000000000 
> +0100
> @@ -0,0 +1,39 @@
> +/* PR fortran/55633 */
> +/* { dg-do run { target int128 } } */
> +
> +extern void abort (void);
> +
> +__attribute__((noinline, noclone)) void
> +bar (__int128_t *x)
> +{
> +  int c = sizeof (__int128_t) * __CHAR_BIT__;
> +  if (c > 127)
> +    c = 127;
> +  if (*x != c)
> +    abort ();
> +}
> +
> +__attribute__((noinline)) void
> +foo (void)
> +{
> +  __int128_t m, ma;
> +  ma = 0;
> +  m = 0;
> +  m = ~m;
> +  do
> +    {
> +      if (m == 0 || ma > 126)
> +     break;
> +      ma = ma + 1;
> +      m = ((__uint128_t) m) >> 1;
> +    }
> +  while (1);
> +  bar (&ma);
> +}
> +
> +int
> +main ()
> +{
> +  foo ();
> +  return 0;
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imend

Reply via email to