http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51725
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-01-02 13:52:14 UTC --- Seems that canonical vs. non-canonical VALUEs are mixed up. In cselib_invalidate_mem, we don't terminate the loop: addr = cselib_lookup (XEXP (x, 0), VOIDmode, 0, GET_MODE (x)); mem_chain = &addr->addr_list; for (;;) { if ((*mem_chain)->elt == v) { unchain_one_elt_list (mem_chain); break; } mem_chain = &(*mem_chain)->next; } because v is here a canonical_cselib_val of (*mem_chain)->elt. We could perhaps compare here canonical_cselib_val ((*mem_chain)->elt) == v instead, or just canonicalizing the mem_elt value early when inserting it into addr_list/*_containing_mem fixes this too: --- gcc/cselib.c.jj 2012-01-01 19:54:46.000000000 +0100 +++ gcc/cselib.c 2012-01-02 14:46:51.180804640 +0100 @@ -1264,6 +1264,8 @@ add_mem_for_addr (cselib_val *addr_elt, { struct elt_loc_list *l; + mem_elt = canonical_cselib_val (mem_elt); + /* Avoid duplicates. */ for (l = mem_elt->locs; l; l = l->next) if (MEM_P (l->loc) ALex?