https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81196

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |NEW
   Last reconfirmed|                            |2017-06-26
                 CC|                            |amker at gcc dot gnu.org,
                   |                            |rguenth at gcc dot gnu.org
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Probably some more elaborate handling in number_of_iterations_cond is required:

  /* We can handle the case when neither of the sides of the comparison is
     invariant, provided that the test is NE_EXPR.  This rarely occurs in
     practice, but it is simple enough to manage.  */
  if (!integer_zerop (iv0->step) && !integer_zerop (iv1->step))
    {
      tree step_type = POINTER_TYPE_P (type) ? sizetype : type;
      if (code != NE_EXPR)
        return false;

      iv0->step = fold_binary_to_constant (MINUS_EXPR, step_type,
                                           iv0->step, iv1->step);
      iv0->no_overflow = false;
      iv1->step = build_int_cst (step_type, 0);
      iv1->no_overflow = true;
    }

I think this exit is premature and the following works for the testcase.
I suppose exiting is still required but can be moved to a later point,
or the helpers now fully handle the case of non-constant iv1 ...
Vectorization still fails with this due to runtime aliasing so it
probably exposes some wrong-code issue.  CCing Bin who is now most
familiar with the niter code.

Index: gcc/tree-ssa-loop-niter.c
===================================================================
--- gcc/tree-ssa-loop-niter.c   (revision 249638)
+++ gcc/tree-ssa-loop-niter.c   (working copy)
@@ -1674,14 +1674,14 @@ number_of_iterations_cond (struct loop *
   if (!integer_zerop (iv0->step) && !integer_zerop (iv1->step))
     {
       tree step_type = POINTER_TYPE_P (type) ? sizetype : type;
-      if (code != NE_EXPR)
-       return false;
-
-      iv0->step = fold_binary_to_constant (MINUS_EXPR, step_type,
-                                          iv0->step, iv1->step);
-      iv0->no_overflow = false;
-      iv1->step = build_int_cst (step_type, 0);
-      iv1->no_overflow = true;
+      if (code == NE_EXPR)
+       {
+         iv0->step = fold_binary_to_constant (MINUS_EXPR, step_type,
+                                              iv0->step, iv1->step);
+         iv0->no_overflow = false;
+         iv1->step = build_int_cst (step_type, 0);
+         iv1->no_overflow = true;
+       }
     }

   /* If the result of the comparison is a constant,  the loop is weird.  More

Reply via email to