https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79159
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |amker at gcc dot gnu.org --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- Suspiciously similar to PR71437 we have different ASSERT_EXPR order for the first if (i_1 < _9) / if (_2 > _i_3) condition which downthread leads to different value numbers. In this case the "good" order is the other one though... (but it produces the same good symbolic range): here i_1 = [0, 0] and _9 is VARYING. Visiting statement: i_2 = ASSERT_EXPR <i_1, i_1 < _9>; Applying pattern match.pd:695, generic-match.c:64 Applying pattern match.pd:732, generic-match.c:10709 Intersecting [-INF, _9 + -1] EQUIVALENCES: { i_1 } (1 elements) and [0, 0] Applying pattern match.pd:1771, generic-match.c:1258 Applying pattern match.pd:1771, generic-match.c:1258 to [-INF, _9 + -1] EQUIVALENCES: { i_1 } (1 elements) Found new range for i_2: [-INF, _9 + -1] Visiting statement: _36 = ASSERT_EXPR <_9, _9 > i_2>; Intersecting [i_2 + 1, +INF] EQUIVALENCES: { _9 } (1 elements) and VARYING to [i_2 + 1, +INF] EQUIVALENCES: { _9 } (1 elements) Found new range for _36: [i_2 + 1, +INF] and for the bad case, i_3 is [0, 0], _2 is VARYING: Visiting statement: _40 = ASSERT_EXPR <_2, _2 > i_3>; Intersecting [1, +INF] EQUIVALENCES: { _2 } (1 elements) and VARYING to [1, +INF] EQUIVALENCES: { _2 } (1 elements) Found new range for _40: [1, +INF] Visiting statement: i_36 = ASSERT_EXPR <i_3, i_3 < _40>; Intersecting [-INF, 2147483646] EQUIVALENCES: { i_3 } (1 elements) and [0, 0] to [0, 0] EQUIVALENCES: { i_3 } (1 elements) Intersecting [0, 0] EQUIVALENCES: { i_3 } (1 elements) and [0, +INF] to [0, 0] EQUIVALENCES: { i_3 } (1 elements) Found new range for i_36: [0, 0] Final ranges are i_2: [-INF, _9 + -1] EQUIVALENCES: { i_1 } (1 elements) _36: [i_2 + 1, +INF] EQUIVALENCES: { _9 } (1 elements) vs. i_36: [0, 2147483646] EQUIVALENCES: { i_3 } (1 elements) _40: [1, +INF] EQUIVALENCES: { _2 } (1 elements) and the array ref we warn for has j_11: [-INF, _56 + -1] EQUIVALENCES: { j_54 } (1 elements) vs. j_1: [9, 2147483646] EQUIVALENCES: { j_54 } (1 elements) where we simply give up for the symbolic range case on the GCC 6 branch. So the issue is not really VRP but that peeling of the inner loop sometimes produces an extra copy with an out-of-bound access and even VRP cannot prove the block is never reached. It's guarded by if (_4 > j_54) and we have _4: [9, +INF] EQUIVALENCES: { _2 _40 _41 _45 _46 _50 _51 _55 _56 } (9 elements) j_54: [9, +INF(OVF)]