On Fri, 19 Feb 2021, Jakub Jelinek wrote: > Hi! > > The verifiers require that DECL_NONLOCAL or EH_LANDING_PAD_NR > labels are always the first label if there is more than one label. > > When merging blocks, we don't honor that though. > On the following testcase, we try to merge blocks: > <bb 13> [count: 0]: > <L2>: > S::~S (&s); > > and > <bb 15> [count: 0]: > <L0>: > resx 1 > > where <L2> is landing pad and <L0> is FORCED_LABEL. And the code puts > the FORCED_LABEL before the landing pad label, violating the verification > requirements. > > The following patch fixes it by moving the FORCED_LABEL after the > DECL_NONLOCAL or EH_LANDING_PAD_NR label if it is the first label. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Huh, wasn't aware of such. OK. Richard. > 2021-02-19 Jakub Jelinek <ja...@redhat.com> > > PR ipa/99034 > * tree-cfg.c (gimple_merge_blocks): If bb a starts with eh landing > pad or non-local label, put FORCED_LABELs from bb b after that label > rather than before it. > > * g++.dg/opt/pr99034.C: New test. > > --- gcc/tree-cfg.c.jj 2021-02-18 16:20:57.053826485 +0100 > +++ gcc/tree-cfg.c 2021-02-18 19:15:48.436526437 +0100 > @@ -2124,7 +2124,17 @@ gimple_merge_blocks (basic_block a, basi > if (FORCED_LABEL (label)) > { > gimple_stmt_iterator dest_gsi = gsi_start_bb (a); > - gsi_insert_before (&dest_gsi, stmt, GSI_NEW_STMT); > + tree first_label = NULL_TREE; > + if (!gsi_end_p (dest_gsi)) > + if (glabel *first_label_stmt > + = dyn_cast <glabel *> (gsi_stmt (dest_gsi))) > + first_label = gimple_label_label (first_label_stmt); > + if (first_label > + && (DECL_NONLOCAL (first_label) > + || EH_LANDING_PAD_NR (first_label) != 0)) > + gsi_insert_after (&dest_gsi, stmt, GSI_NEW_STMT); > + else > + gsi_insert_before (&dest_gsi, stmt, GSI_NEW_STMT); > } > /* Other user labels keep around in a form of a debug stmt. */ > else if (!DECL_ARTIFICIAL (label) && MAY_HAVE_DEBUG_BIND_STMTS) > --- gcc/testsuite/g++.dg/opt/pr99034.C.jj 2021-02-18 19:05:27.205347304 > +0100 > +++ gcc/testsuite/g++.dg/opt/pr99034.C 2021-02-18 19:07:32.352973196 > +0100 > @@ -0,0 +1,23 @@ > +// PR ipa/99034 > +// { dg-do compile } > +// { dg-options "-O2" } > + > +void *b[5]; > +void foo (void); > +struct S { ~S (); }; > + > +static inline void > +__attribute__((always_inline)) > +bar (int d) > +{ > + S s; > + while (d) > + foo (); > +} > + > +void > +baz (void) > +{ > + bar (2); > + __builtin_setjmp (b); > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)