aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2020-12-01 16:23:59 +0100
committerJakub Jelinek <jakub@redhat.com>2020-12-01 16:23:59 +0100
commit404d0ca7820bbf258e2edfac423403ee31b48a7b (patch)
tree90e880c11190e9340ba71fe640cf175d4781819c
parent2133e773ab855af036de5f6f29eae30d43f1422b (diff)
loop-invariant: JUMP_INSNs aren't loop invariant [PR97954]
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.
-rw-r--r--gcc/loop-invariant.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr97954.c12
2 files changed, 16 insertions, 0 deletions
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index 37ae6549e56..653e3033271 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -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
index 00000000000..178e1d2e965
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97954.c
@@ -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;
+}