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; }