On Fri, 16 Dec 2022, Jakub Jelinek wrote: > Hi! > > The RTL loop passes only request simple preheaders, but don't require > fallthru preheaders, while move_invariant_reg apparently assumes the > latter, that it can just append instruction(s) to the end of the preheader > basic block. > > The following patch fixes that by splitting the preheader edge if > the preheader bb ends with a JUMP_INSN (asm goto in this case). > Without that we get control flow in the middle of a bb. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. > 2022-12-16 Jakub Jelinek <ja...@redhat.com> > > PR rtl-optimization/106751 > * loop-invariant.cc (move_invariant_reg): If preheader bb ends > with a JUMP_INSN, split the preheader edge and emit invariants > into the new preheader basic block. > > * gcc.c-torture/compile/pr106751.c: New test. > > --- gcc/loop-invariant.cc.jj 2022-01-18 11:58:59.683980614 +0100 > +++ gcc/loop-invariant.cc 2022-12-15 17:14:32.906883258 +0100 > @@ -1837,6 +1837,8 @@ move_invariant_reg (class loop *loop, un > else if (dump_file) > fprintf (dump_file, "Invariant %d moved without introducing a new " > "temporary register\n", invno); > + if (JUMP_P (BB_END (preheader))) > + preheader = split_edge (loop_preheader_edge (loop)); > reorder_insns (inv->insn, inv->insn, BB_END (preheader)); > df_recompute_luids (preheader); > > --- gcc/testsuite/gcc.c-torture/compile/pr106751.c.jj 2022-12-15 > 17:44:35.602519711 +0100 > +++ gcc/testsuite/gcc.c-torture/compile/pr106751.c 2022-12-15 > 17:44:21.789721827 +0100 > @@ -0,0 +1,17 @@ > +/* PR rtl-optimization/106751 */ > + > +int *foo (void); > + > +void > +bar (void) > +{ > + asm goto ("" : : : : lab); > + __builtin_unreachable (); > +lab: > + while (1) > + { > + int o; > + asm ("" : "=r" (o) : "g" (1)); > + *foo () = o; > + } > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman; HRB 36809 (AG Nuernberg)