https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87132
--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> --- Simplified: extern void abort (void); int c, d; int main() { int e[] = {4, 4, 4, 4, 4, 4, 4, 4, 4}; d = 8; for (; d; d--) for (int a = 0; a <= 8; a++) { c = e[1]; e[d] = 0; } if (c != 0) abort (); return 0; } this one is going to be interesting to fix. The issue is that we either stop iterating too early or we over-eagerly use values from the previous iteration when walk_non_aliased_vuses skips over e[d] = 0 when looking for aliasing defs to e[1]. d still has the previous iteration value of 8 because we didn't yet re-visit the load of it when walking defs across the backedge. So this is static void * vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, bool *disambiguate_only) { ... /* First try to disambiguate after value-replacing in the definitions LHS. */ if (is_gimple_assign (def_stmt)) { ... lhs_ops = valueize_refs_1 (lhs_ops, &valueized_anything, true); as well as the load from e[1] in the first iteration not needing to visit e[d] because of the not yet executable backedge and thus the virtual PHI degenerating to the entry value. A fix could be somehow tracking memory state changes and iterating once more or avoiding last-iteration values in valueization (or valueization completely when performing the walk over backedges). The latter latter is easiest, testing that for fallout. Index: gcc/tree-ssa-alias.c =================================================================== --- gcc/tree-ssa-alias.c (revision 263944) +++ gcc/tree-ssa-alias.c (working copy) @@ -2722,7 +2722,14 @@ next:; if (arg1 == arg0) ; else if (! maybe_skip_until (phi, arg0, ref, arg1, cnt, visited, - abort_on_visited, translate, data)) + abort_on_visited, + /* Do not translate when walking over + backedges. */ + dominated_by_p + (CDI_DOMINATORS, + gimple_bb (SSA_NAME_DEF_STMT (arg1)), + phi_bb) + ? NULL : translate, data)) return NULL_TREE; }