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;