On Fri, 12 Apr 2019, Jakub Jelinek wrote: > Hi! > > In the following testcase, we have initially during RTL expansion a call > which can throw, followed by fallthrough into an empty block with two > similar predecessors (both calling the same function) and with a fallthrough > into an empty block with no successors (__builtin_unreachable). > That last block is optimized away soon and in the cfglayout mode we have > a bb with no successors that has a BARRIER in BB_FOOTER. During cfg cleanup > during combine we actually optimize away even that other empty bb with no > successors, but end up not putting a BARRIER into BB_FOOTER of the bb with a > call. There is in the following hunk in try_optimize_cfg code to handle > that, but a) it assumes a BARRIER has to be the first in BB_FOOTER, which > as all other spots I've found don't assume, even for the non-cfglayout > mode a few lines below we call get_last_bb_insn which walks the following > insn chain (note, this isn't a problem on this exact testcase though) > and b) punt if e->src bb already has non-NULL BB_FOOTER (that is what > breaks this testcase - the testcase has a NOTE_INSN_DELETED_LABEL in > BB_FOOTER, but of course no BARRIER, we don't add one here and later on > when outof_cfglayout we ICE because there is no BARRIER after a bb that > doesn't fall thru). Apparently there is a function which can handle > adding a barrier, both into an empty BB_FOOTER as well as when there is > a BB_FOOTER, but doesn't contain a BARRIER in there. > > So, this patch fixes both issues. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
LGTM. Richard. > 2019-04-12 Jakub Jelinek <ja...@redhat.com> > > PR rtl-optimization/90026 > * cfgcleanup.c (try_optimize_cfg): When removing empty bb with no > successors, look for BARRIERs inside of the whole BB_FOOTER chain > rather than just at the start of it. If e->src BB_FOOTER is not NULL > in cfglayout mode, use emit_barrier_after_bb. > > * g++.dg/opt/pr90026.C: New test. > > --- gcc/cfgcleanup.c.jj 2019-03-09 09:25:11.743785011 +0100 > +++ gcc/cfgcleanup.c 2019-04-11 11:30:52.967173100 +0200 > @@ -2712,23 +2712,23 @@ try_optimize_cfg (int mode) > > if (current_ir_type () == IR_RTL_CFGLAYOUT) > { > - if (BB_FOOTER (b) > - && BARRIER_P (BB_FOOTER (b))) > + rtx_insn *insn; > + for (insn = BB_FOOTER (b); > + insn; insn = NEXT_INSN (insn)) > + if (BARRIER_P (insn)) > + break; > + if (insn) > FOR_EACH_EDGE (e, ei, b->preds) > - if ((e->flags & EDGE_FALLTHRU) > - && BB_FOOTER (e->src) == NULL) > + if ((e->flags & EDGE_FALLTHRU)) > { > - if (BB_FOOTER (b)) > + if (BB_FOOTER (b) > + && BB_FOOTER (e->src) == NULL) > { > BB_FOOTER (e->src) = BB_FOOTER (b); > BB_FOOTER (b) = NULL; > } > else > - { > - start_sequence (); > - BB_FOOTER (e->src) = emit_barrier (); > - end_sequence (); > - } > + emit_barrier_after_bb (e->src); > } > } > else > --- gcc/testsuite/g++.dg/opt/pr90026.C.jj 2019-04-11 12:40:14.508840308 > +0200 > +++ gcc/testsuite/g++.dg/opt/pr90026.C 2019-04-11 12:39:43.431352423 > +0200 > @@ -0,0 +1,24 @@ > +// PR rtl-optimization/90026 > +// { dg-do compile } > +// { dg-options "-fnon-call-exceptions -ftracer -O2 -w" } > + > +typedef __SIZE_TYPE__ size_t; > +struct S { int *b; ~S () { delete b; } }; > +void bar (); > +char c[sizeof (int)]; > + > +void * > +operator new (size_t, void *) > +{ > + __builtin_unreachable (); > +} > + > +void > +foo () > +{ > + S a; > + if (a.b) > + a.b = new int (); > + bar (); > + new (c) int (); > +} > > Jakub > -- Richard Biener <rguent...@suse.de> SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG Nürnberg)