https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113879
--- Comment #2 from Andrew Macleod <amacleod at redhat dot com> --- Not so much a cycle issue as a backward propagation issue. <bb 2> : goto <bb 6>; [INV] <bb 3> : _1 = (long unsigned int) j_10; <..> if (j_10 >= -1) goto <bb 4>; [INV] else goto <bb 5>; [INV] <bb 4> : __builtin_trap (); <bb 5> : j_18 = j_10 + 1; <bb 6> : # j_10 = PHI <i_12(D)(2), j_18(5)> _9 = i_12(D) + 3; if (_9 >= j_10) goto <bb 3>; [INV] else goto <bb 7>; [INV] <bb 7> : return; 'i' is only ever referenced twice. Very first thing on the edge from 2->6 as the initial value for j_10, and then in the calculation of _9 which is then used in the branch against j_10. That initial value of i_12 we have no way of knowing can't be INT_MAX. Its only later during the calculation _9 = i_12 + 3 that we can infer that i_12 must be INT_MAX-3. We certainly know after the branch that 6->3 (T) i_12(D) : [irange] int [-INF, 2147483644] Going back to examine the initial value use on the edge 2->6 is not something that we would normally expect to have to do. Its similar to the __builtin_unreachable() problem in that we can infer the global range of i_12 based on that addition statement, but detecting that is the case in general circumstance is not trivial as we have to go look at all earlier uses to make sure they are post dominated by the statement. There is also the additional option that I do no believe we currently register an inferred range on the statement _9 = i_12(D) + 3; for i_12. Adding an inferred range for every arithmetic statement would come with a cost.. not sure exactly what it would be, but we weren't expecting inferred ranges from the majority of statements. we don't normally need that because as you can see, we get the ranges right after the branches anyway. I could do a dry run and see what the time differential is. We could consider adding those inferred ranges at -O3. we could also consider an enhancement that works like the builtin_unreachable() removal pass, but looks at all inferred ranges in the function as well to see if they are applicable in a global context and adjusts the global value if appropriate. Which they would be in a case like this.