https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111901
--- Comment #14 from Richard Sandiford <rsandifo at gcc dot gnu.org> --- ISTM that the problem is that cselib doesn't consider: (clobber (mem:BLK (scratch))) to be a read from memory (unlike note_uses, which gets this right). cselib instead assumes that the SET_SRC of the asm is self-contained, and doesn't depend on anything outside the SET_SRC. This seems like a representational issue. It would be better if the SET_SRC contained (mem:BLK (scratch)), which is what I'd expect an md insn to do. So as it stands, I think the equivalence recorded by cselib_record_sets is simply bogus: the instruction itself invalidates the equivalence that is being recorded. All the other breakage seems to be a downstream effect of that. One hacky fix would be: diff --git a/gcc/cselib.cc b/gcc/cselib.cc index 7f1991b09c3..673fda30f3a 100644 --- a/gcc/cselib.cc +++ b/gcc/cselib.cc @@ -3024,6 +3024,7 @@ cselib_record_sets (rtx_insn *insn) int n_sets_before_autoinc; int n_strict_low_parts = 0; struct cselib_record_autoinc_data data; + bool has_mem_clobber = false; rtx body = PATTERN (insn); if (GET_CODE (body) == COND_EXEC) @@ -3053,9 +3054,14 @@ cselib_record_sets (rtx_insn *insn) sets[n_sets].dest = SET_DEST (x); n_sets++; } + else if (GET_CODE (x) == CLOBBER && MEM_P (XEXP (x, 0))) + has_mem_clobber = true; } } + if (has_mem_clobber) + n_sets = 0; + if (n_sets == 1 && MEM_P (sets[0].src) && !cselib_record_memory but that doesn't feel like the best approach…