[committed] [PR rtl-optimization/90275] Another 90275 related cse.c fix
authorJeff Law <law@redhat.com>
Fri, 17 Apr 2020 21:38:13 +0000 (15:38 -0600)
committerJeff Law <law@redhat.com>
Fri, 17 Apr 2020 21:40:43 +0000 (15:40 -0600)
This time instead of having a NOP copy insn that we can completely ignore and
ultimately remove, we have a NOP set within a multi-set PARALLEL.  It triggers,
the same failure when the source of such a set is a hard register for the same
reasons as we've already noted in the BZ and patches-to-date.

For prior cases we've been able to mark the insn as a nop set and ignore it for
the rest of cse_insn, ultimately removing it.  That's not really an option here
as there are other sets that we have to preserve.

We might be able to fix this instance by splitting the multi-set insn, but I'm
not keen to introduce splitting into cse.  Furthermore, the target may not be
able to split the insn.  So I considered this is non-starter.

What I finally settled on was to use the existing do_not_record machinery to
ignore the nop set within the parallel (and only that set within the parallel).

One might argue that we should always ignore a REG_UNUSED set.  But I rejected
that idea -- we could have cse-able divmod insns where the first had a
REG_UNUSED note for a destination, but the second did not.

One might also argue that we could have a nop set without a REG_UNUSED in a
multi-set parallel and thus we could trigger yet another insert_regs ICE at
some point.  I tend to think this is a possibility.  If we see this happen,
we'll have to revisit.

PR rtl-optimization/90275
* cse.c (cse_insn): Avoid recording nop sets in multi-set parallels
when the destination has a REG_UNUSED note.

gcc/ChangeLog
gcc/cse.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr90275-2.c [new file with mode: 0644]

index 93badc209ae17760e6a5f0b8a17aad6adde38360..47f22327542ab037c2b6b0f3b4e9e2f3f246dc7d 100644 (file)
@@ -1,3 +1,9 @@
+2020-04-17  Jeff Law  <law@redhat.com>
+
+       PR rtl-optimization/90275
+       * cse.c (cse_insn): Avoid recording nop sets in multi-set parallels
+       when the destination has a REG_UNUSED note.
+
 2020-04-17  Tobias Burnus  <tobias@codesourcery.com>
 
        PR middle-end/94635
index f07bbdbebadab8a0d4fad70e6b6a4b8cd9853984..5aaba8d80e091987b586242b14c3b25ef0e64df1 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4715,8 +4715,20 @@ cse_insn (rtx_insn *insn)
 
       /* Compute SRC's hash code, and also notice if it
         should not be recorded at all.  In that case,
-        prevent any further processing of this assignment.  */
-      do_not_record = 0;
+        prevent any further processing of this assignment.
+
+        We set DO_NOT_RECORD if the destination has a REG_UNUSED note.
+        This avoids getting the source register into the tables, where it
+        may be invalidated later (via REG_QTY), then trigger an ICE upon
+        re-insertion.
+
+        This is only a problem in multi-set insns.  If it were a single
+        set the dead copy would have been removed.  If the RHS were anything
+        but a simple REG, then we won't call insert_regs and thus there's
+        no potential for triggering the ICE.  */
+      do_not_record = (REG_P (dest)
+                      && REG_P (src)
+                      && find_reg_note (insn, REG_UNUSED, dest));
       hash_arg_in_memory = 0;
 
       sets[i].src = src;
index 030550f16619b1112df328628f2e800dde6c0cf4..e5d0d92344ce8713d2fb23fb48fd9f0a2512fdb5 100644 (file)
@@ -1,3 +1,8 @@
+2020-04-17  Jeff Law  <law@redhat.com>
+
+       PR rtl-optimization/90275
+       * gcc.c-torture/compile/pr90275-2.c: New test.
+
 2020-04-17  Patrick Palka  <ppalka@redhat.com>
 
        PR c++/94483
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr90275-2.c b/gcc/testsuite/gcc.c-torture/compile/pr90275-2.c
new file mode 100644 (file)
index 0000000..9ebf7d9
--- /dev/null
@@ -0,0 +1,12 @@
+
+void
+a() {
+  short *b;
+  short c;
+  long long *d = a;
+  for (;;) {
+    long long *e = a;
+    (*d *= *e - c) / *b ?: (*b = 0);
+  }
+}
+