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

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
So PR81196 is exactly the bug the code in niter analysis was added for.
We have

  for (;p<q; ++p,--q)

and thus {p, +1} < {q, -1} where moving the step yields {p, +2} < q.
That's not valid according to the rules laid out by fold_comparison.
For example with p = INT_MAX-1 and q = INT_MAX initially p < q will
hold and so we compute (INT_MAX-1) + 1 < INT_MAX - 1 which will
not overflow and terminate the loop.  But re-formulated as
(INT_MAX-1) + 2 < INT_MAX will overflow and not terminate the loop.

For the testcase in the bug we have additional knowledge though, we
can relate the BASE of the IVs which are p_6 + 2 and p_6 + 508
respectively.

Before the fix we'd do

Analyzing # of iterations of loop 1
  exit condition [p_3(D) + 1, + , 2] < q_4(D) + -1
  bounds on difference of bases: -1 ... 4294967293
  result:
    # of iterations (((unsigned int) q_4(D) - (unsigned int) p_3(D)) +
4294967295) / 2, bounded by 2147483647

which is even correct and we are not reflecting the invalid exit condition
transform into the IL.

So besides of handling the case where we can relate the IV bases we
possibly want to see whether the exit condition transform is really
required for what we compute later.  Testcase for which the exit
test transform is not valid (but it's not miscompiled):

void __attribute__((noipa))
foo (int p, int q)
{
  for (;p<q;++p,--q)
    __asm__ volatile ("");
}

int main()
{
  foo (__INT_MAX__ - 1, __INT_MAX__);
  return 0;
}

Reply via email to