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

--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
Btw, to me it seems that since we are resolving condition 1) statically we know
that the difference of iv->base and final is positive with infinite
precision and fits the unsigned niter_type.  To avoid going to the unsigned
type we can then indeed check multiple_of_p on each component, but we need
to use the original signedness here (or rather always signed?).

Using unsigned arithmetic for the

          niter->niter = fold_build2 (EXACT_DIV_EXPR, niter_type, c, s);

in the end is consistent with the conditions we checked.  So to preserve the
gist of Bins change I included it should probably read

diff --git a/gcc/tree-ssa-loop-niter.cc b/gcc/tree-ssa-loop-niter.cc
index 318d10c8fac..3ddc3a5c3a6 100644
--- a/gcc/tree-ssa-loop-niter.cc
+++ b/gcc/tree-ssa-loop-niter.cc
@@ -986,6 +986,7 @@ number_of_iterations_ne (class loop *loop, tree type,
affine_iv *iv,
                         bool exit_must_be_taken, bounds *bnds)
 {
   tree niter_type = unsigned_type_for (type);
+  tree stype = signed_type_for (niter_type);
   tree s, c, d, bits, assumption, tmp, bound;
   mpz_t max;

@@ -1051,10 +1052,10 @@ number_of_iterations_ne (class loop *loop, tree type,
affine_iv *iv,
      along with condition 1) or 1').  */
   if (!niter->control.no_overflow
       && (integer_onep (s)
-         || (multiple_of_p (type, fold_convert (niter_type, iv->base), s,
-                            false)
-             && multiple_of_p (type, fold_convert (niter_type, final), s,
-                               false))))
+         || (multiple_of_p (stype, fold_convert (stype, iv->base),
+                            fold_convert (stype, iv->step))
+             && multiple_of_p (stype, fold_convert (stype, final),
+                               fold_convert (stype, iv->step)))))
     {
       tree t, cond, relaxed_cond = boolean_false_node;

Reply via email to