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…

Reply via email to