https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64491
--- Comment #11 from Andrew Stubbs <ams at gcc dot gnu.org> --- The compiler has constructed the loop such that it reads like this: f = 0; tmp = 0; do { B[f] = tmp | A[f + 1]; if (f + 1 == 8) break; if (f + 1 > 0) tmp = A[f]; if (f + 1 == 7) { B[f + 1] = tmp; break; } f++; } while (1); It calculates the upper bound for f to be 7, which would make f + 1 a problem. maybe_lower_iteration_bound then correctly identifies this, and reduces the upper bound to 6. Consequently, the unnecessary "if (f + 1 == 8)" is removed, and all is well with the world. The problem is that leaves no path, from the loop header, that reaches a loop exit without passing the "undefined" statement. This makes it difficult to tell the difference between UB in the source code, and this temporary UB introduced by the compiler. I've no idea why the bounds are reduced here, rather than set properly in the first place? I've tried only warning when *all* the exit routes are to be removed, but they're not all listed in loop->bounds, so I'm stuck.