On Thu, Sep 2, 2021 at 6:18 PM Richard Biener <rguent...@suse.de> wrote:
>
> On Thu, 2 Sep 2021, Jiufu Guo wrote:
>
> > When transform
> >   {iv0.base, iv0.step} LT/LE {iv1.base, iv1.step}
> > to
> >   {iv0.base, iv0.step - iv1.step} LT/LE {iv1.base, 0}
> >
> > There would be error if 'iv0.step - iv1.step' in negative,
> > for which means run until wrap/overflow.
> >
> > For example:
> >    {1, +, 1} <= {4, +, 3} => {1, +, -2} <= {4, +, 0}
> >
> > This patch avoid this kind transform.
> >
> > Bootstrap and regtest pass on ppc64le.
> > Is this ok for trunk?
>
> This looks like PR100740, see the discussion starting at
> https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571570.html
>
> We seem to be at a dead end figuring what's exactly required
> to make the transform valid and I have my doubts that arguing
> with overflow we're not running in circles.
>
> My last attempt was
>
> +      if (code != NE_EXPR)
> +       {
> +         if (TREE_CODE (step) != INTEGER_CST)
> +           return false;
> +         if (!iv0->no_overflow || !iv1->no_overflow)
> +           return false;
> +         /* The new IV does not overflow if the step has the same
> +            sign and is less in magnitude.  */
> +         if (tree_int_cst_sign_bit (iv0->step) != tree_int_cst_sign_bit
> (step)
> +             || wi::geu_p (wi::abs (wi::to_wide (step)),
> +                           wi::abs (wi::to_wide (iv0->step))))
> +           return false;
> +       }
>
> where your patch at least misses { 1, +, -1 } < { -3, + , -3 }
> transforming to { 1, +, +2 } < -3, thus a positive step but
> we're still iterating unti wrap?  That is, the sign of the
> combined step cannot really be the issue at hand.
>
> Bin argued my condition is too strict and I agreed, see
> https://gcc.gnu.org/pipermail/gcc-patches/2021-July/574334.html
> which is the last mail in the thread sofar (still without a fix :/)
>
> Somewhere it was said that we eventually should simply put
> preconditions into ->assumptions rather than trying to
> check ->no_overflow and friends, not sure if that's really
I did some experiments which can fix the PRs, however it causes new
failures in graphite possibly because of missing cases.  However, I
didn't have time looking into graphite tests back in time.

Thanks,
bin
> applicable here.
>
> Richard.
>
> > BR.
> > Jiufu
> >
> > gcc/ChangeLog:
> >
> > 2021-09-02  Jiufu Guo  <guoji...@linux.ibm.com>
> >
> >       PR tree-optimization/102131
> >       * tree-ssa-loop-niter.c (number_of_iterations_cond):
> >       Avoid transform until wrap condition
> >
> > gcc/testsuite/ChangeLog:
> >
> > 2021-09-02  Jiufu Guo  <guoji...@linux.ibm.com>
> >
> >       PR tree-optimization/102131
> >       * gcc.dg/pr102131.c: New test.
> >
> > ---
> >  gcc/tree-ssa-loop-niter.c       | 18 +++++++++
> >  gcc/testsuite/gcc.dg/pr102131.c | 69 +++++++++++++++++++++++++++++++++
> >  2 files changed, 87 insertions(+)
> >  create mode 100644 gcc/testsuite/gcc.dg/pr102131.c
> >
> > diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
> > index 7af92d1c893..52ce517af89 100644
> > --- a/gcc/tree-ssa-loop-niter.c
> > +++ b/gcc/tree-ssa-loop-niter.c
> > @@ -1866,6 +1866,24 @@ number_of_iterations_cond (class loop *loop,
> >             || !iv0->no_overflow || !iv1->no_overflow))
> >       return false;
> >
> > +      /* GT/GE has been transformed to LT/LE already.
> > +     cmp_code could be LT, LE or NE
> > +
> > +     For LE/LT transform
> > +     {iv0.base, iv0.step} LT/LE {iv1.base, iv1.step}
> > +     to
> > +     {iv0.base, iv0.step - iv1.step} LT/LE {iv1.base, 0}
> > +     Negative iv0.step - iv1.step means decreasing until wrap,
> > +     then the transform is not accurate.
> > +
> > +     For example:
> > +     {1, +, 1} <= {4, +, 3}
> > +     is not same with
> > +     {1, +, -2} <= {4, +, 0}
> > +       */
> > +      if ((code == LE_EXPR || code == LT_EXPR) && tree_int_cst_sign_bit 
> > (step))
> > +     return false;
> > +
> >        iv0->step = step;
> >        if (!POINTER_TYPE_P (type))
> >       iv0->no_overflow = false;
> > diff --git a/gcc/testsuite/gcc.dg/pr102131.c 
> > b/gcc/testsuite/gcc.dg/pr102131.c
> > new file mode 100644
> > index 00000000000..0fcfaa132da
> > --- /dev/null
> > +++ b/gcc/testsuite/gcc.dg/pr102131.c
> > @@ -0,0 +1,69 @@
> > +/* { dg-do run } */
> > +
> > +unsigned int a;
> > +int
> > +fun1 ()
> > +{
> > +  unsigned b = 0;
> > +  int c = 1;
> > +  for (; b < 3; b++)
> > +    {
> > +      while (c < b)
> > +     __builtin_abort ();
> > +      for (a = 0; a < 3; a++)
> > +     c++;
> > +    }
> > +  return 0;
> > +}
> > +
> > +unsigned b;
> > +int
> > +fun2 ()
> > +{
> > +  unsigned c = 0;
> > +  for (a = 0; a < 2; a++)
> > +    for (b = 0; b < 2; b++)
> > +      if (++c < a)
> > +     __builtin_abort ();
> > +  return 0;
> > +}
> > +
> > +int
> > +fun3 (void)
> > +{
> > +  unsigned a, b, c = 0;
> > +  for (a = 0; a < 10; a++)
> > +    {
> > +      for (b = 0; b < 2; b++)
> > +     {
> > +       c++;
> > +       if (c < a)
> > +         {
> > +           __builtin_abort ();
> > +         }
> > +     }
> > +    }
> > +  return 0;
> > +}
> > +
> > +int
> > +fun4 ()
> > +{
> > +  unsigned i;
> > +  for (i = 0; i < 3; ++i)
> > +    {
> > +      if (i > i * 2)
> > +     __builtin_abort ();
> > +    }
> > +  return 0;
> > +}
> > +
> > +int
> > +main ()
> > +{
> > +  fun1 ();
> > +  fun2 ();
> > +  fun3 ();
> > +  fun4 ();
> > +  return 0;
> > +}
> >
>
> --
> Richard Biener <rguent...@suse.de>
> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
> Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to