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.

Reply via email to