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)

Reply via email to