loop-invariant: JUMP_INSNs aren't loop invariant [PR97954]
authorJakub Jelinek <jakub@redhat.com>
Tue, 1 Dec 2020 15:23:59 +0000 (16:23 +0100)
committerJakub Jelinek <jakub@redhat.com>
Tue, 1 Dec 2020 15:23:59 +0000 (16:23 +0100)
The following testcase ICEs because loop invariant motion moves asm goto
with a single output as invariant.
Normally, jumps aren't really moved, because if they are single set,
they have their SET_DEST (pc) and pc_rtx has VOIDmode on which one of the
functions find_invariant_insn calls bails out.  The code already punts on
insns that can throw or trap.  And for asm goto without outputs, it isn't
single set, or asm goto with two or more outputs it isn't single set either.

2020-12-01  Jakub Jelinek  <jakub@redhat.com>

PR rtl-optimization/97954
* loop-invariant.c (find_invariant_insn): Punt on JUMP_P insns.

* gcc.dg/pr97954.c: New test.

gcc/loop-invariant.c
gcc/testsuite/gcc.dg/pr97954.c [new file with mode: 0644]

index 37ae6549e56fc2f898d85e2b0dea445567cbc539..653e3033271d82c5f69ec19cf8b553a332d9f617 100644 (file)
@@ -1099,6 +1099,10 @@ find_invariant_insn (rtx_insn *insn, bool always_reached, bool always_executed)
   if (HAVE_cc0 && sets_cc0_p (insn))
     return;
 
+  /* Jumps have control flow side-effects.  */
+  if (JUMP_P (insn))
+    return;
+
   set = single_set (insn);
   if (!set)
     return;
diff --git a/gcc/testsuite/gcc.dg/pr97954.c b/gcc/testsuite/gcc.dg/pr97954.c
new file mode 100644 (file)
index 0000000..178e1d2
--- /dev/null
@@ -0,0 +1,12 @@
+/* PR rtl-optimization/97954 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+  int x;
+ lab:
+  asm goto ("": "=r" (x) : : : lab);
+  return x;
+}