https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55217
--- Comment #5 from Michael Veksler <mickey.veksler at gmail dot com> --- Running the delta.c example with -fdump-tree-all-all-lineno produces delta.c.125t.vrp2. For some reason, stop_9 (which is the first stop_.* in the file) is initialized with stop_9 = barD.1593 (), but it should have been initialized with 0. ============= # i_17 = PHI <[delta.c : 5:36] i_10(4), [delta.c : 5:14] 10(2)> # .MEM_18 = PHI <.MEM_8(4), .MEM_4(D)(2)> [delta.c : 6:13] # .MEM_8 = VDEF <.MEM_18> # USE = nonlocal # CLB = nonlocal stop_9 = barD.1593 (); <====== Weird reorder [delta.c : 5:36] i_10 = i_17 + -1; [delta.c : 5:22] _5 = i_10 >= 0; [delta.c : 5:29] _6 = stop_9 == 0; [delta.c : 5:26] _7 = _6 & _5; [delta.c : 5:5] if (_7 != 0) goto <bb 4>; else goto <bb 5>; ========== This seems wrong because the first time stop == 0 is checked at the source is: int stop= 0; for (int i=10 ; i>=0 && !stop; --i) { ^^^^^ <=== First time stop == 0 is checked. stop= bar(); } } ===== This seems that VRP sees the call to bar() in the wrong place. Another issue is that VRP sees "i>=0 && !stop", which it translates to: Visiting statement: =========== This gives a don't know: =========== [delta.c : 5:26] _7 = _6 & _5; Found new range for _7: [0, +INF] [snip] Predicate evaluates to: DON'T KNOW ================================================================== >From there things go downhill. Instead of knowing that _7 implies _5 (i.e., i>=0), it loses this information. So VRP does not understand that in the loop i>= 0. === This causes the following: ==== i_17: loop information indicates does not overflow Induction variable (int) 9 + -1 * iteration does not wrap in statement i_10 = i_17 + -1; in loop 1. Statement i_10 = i_17 + -1; is executed at most 2147483657 (bounded by 2147483657) + 1 times in loop 1. Found new range for i_17: [-INF, 10] ================================= If it know that _7 implies _5 and hence i>=0 then it could have understood that i_17: [0, 10]. ===== This could lead to missed optimizations (in other cases), and bogus warnings: === Visiting statement: [delta.c : 5:36] i_10 = i_17 + -1; Found new range for i_10: [-INF(OVF), 9]