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

--- Comment #7 from Andrew Macleod <amacleod at redhat dot com> ---
ok, looked deeper.  GCC-13 has the original version of bounds_of_var, so I
traced it.
nit was 0 back then as well, so that is the expected value.
There is a comment:

/* Check if init + nit * step overflows.  Though we checked
   scev {init, step}_loop doesn't wrap, it is not enough
   because the loop may exit immediately.  Overflow could
   happen in the plus expression in this case.  */
if ((dir == EV_DIR_DECREASES && compare_values (maxvr.min (), initvr.min ()) !=
-1)
    || (dir == EV_DIR_GROWS && compare_values (maxvr.max (), initvr.max ()) !=
1))
  return false;

The new code which is suppose to do this performs this check that the direction
of the step is correct,  but there is a subtlety that is overlooked which is
not in the comment.

If nit is 0, as it is in this case, bit maxvr (which is init + nit * step)  and
initvr are equal.  compare_values is checking that the values are either < or >
depending on the direction.   If the values or the same, this test fails, and
we return false.

This is comparable to what I suggested in the previous comment, return 0 if nit
is 0.

I am running that fix through tests now.

Reply via email to