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.

Reply via email to