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)

Reply via email to