https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111601
--- Comment #24 from Jakub Jelinek <jakub at gcc dot gnu.org> --- As the pass seems to work on one basic block at the time (everything from analysis to actual changes), I wonder if e.g. get_uses shouldn't punt if it sees (non-DEBUG_INSN!) uses in other basic block but the current one (this would still not fix this wrong-code) or if the definition's luid is higher than use's luid (i.e. the use is in the same bb, but still from a different iteration of the loop). See the loop: *last_viable = c; *cand = c->next; c->next = (z_candidate *) 0; last_viable = &c->next; if (!*cand) break; c = *cand; goto loop; statements done in the loop body, the *last_viable = c; store is the %r9 store to %r10 (which is initially address of some automatic variable, but &c->next aka c + 96 for second and following iteration), the c->next = 0 store is the %r5 store to %r10 (which has been incremented by 96 first.