Hi! 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.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2020-12-01 Jakub Jelinek <ja...@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.jj 2020-01-12 11:54:36.000000000 +0100 +++ gcc/loop-invariant.c 2020-11-30 09:56:37.022696142 +0100 @@ -1099,6 +1099,10 @@ find_invariant_insn (rtx_insn *insn, boo 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; --- gcc/testsuite/gcc.dg/pr97954.c.jj 2020-11-30 10:31:54.870891248 +0100 +++ gcc/testsuite/gcc.dg/pr97954.c 2020-11-30 10:31:08.875407984 +0100 @@ -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; +} Jakub