https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120560
Andrew Macleod <amacleod at redhat dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |ASSIGNED
Assignee|unassigned at gcc dot gnu.org |amacleod at redhat dot
com
--- Comment #8 from Andrew Macleod <amacleod at redhat dot com> ---
Created attachment 62480
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=62480&action=edit
proposed fix
OK, after more poking, this is the real fix.
The original code during the final comparison used
/* 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 did the same check in a slightly different way. IN this case,
compare_values must return -1 or 1, which means A < B or A >B.
if A == B, it returns false.
The new code used wi::gt_p to look for the failure case, which means if the 2
values are the same, it will not fail, and we will produce a range.
The fix is to change it to use wi::ge_p which will again return false when the
2 values are the same.
Running through regression testing now.