https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122537
--- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> ---
[a.1_16 + -72, + , -61] >= a.1_16 + -19 is what we start with, from header
copying the loop to
c = 69;
do
{
c += -61;
}
while (a - 80 + c >= a - 19);
which correctly indicates the loop does not iterate at all. But we
cannot determine this statically because a.1_16 + -72 >= a.1_16 + -19
is not known if the computation might overflow (-fwrapv).
Turning that into LT registers the a.1_16 != -2147483629 assumption
(so a.1_16 + -19 - 1 does not wrap).
But number_of_iterations_lt_to_ne fails to register the may-be-zero
condition because of 'bnds' we recorded and 'mmod'.
/* IV0 < IV1 does not loop if IV0->base >= IV1->base. */
if (mpz_cmp (mmod, bnds->below) < 0)
noloop = boolean_false_node;
else
noloop = fold_build2 (GE_EXPR, boolean_type_node,
iv0->base, iv1->base);
mmod is -56 and bnds->below is -52.
I'm unsure
bounds_add (bnds, 1, type1);
is correct when le to lt in number_of_iterations_le. We turn
[-53, 4294967243] into [-52, 4294967244] here, but that decreases
->below in magnitude.
In number_of_iterations_lt we happily compute a constant delta between
the bases. For step == 1 we'd have added may_be_zero iff
if (mpz_sgn (bnds->below) < 0)
niter->may_be_zero = fold_build2 (LT_EXPR, boolean_type_node,
iv1->base, iv0->base);
but number_of_iterations_lt_to_ne has that extra "optimization". It
also possibly computes mmod based on the garbage 'delta'.
I've patched that thing in the past, with r15-5496-gff5a14abeb31cd.
But I think that we have to assert fv_comp_no_overflow before using
the short-cut.
Testing a patch.