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;