On Fri, 17 Apr 2020, Jakub Jelinek wrote:

> Hi!
> 
> delete_insn_and_edges calls purge_dead_edges whenever deleting the last insn
> in a bb, whatever it is.  If it called it only for mandatory last insns
> in the basic block (that may not be followed by DEBUG_INSNs, dunno if that
> is control_flow_insn_p or something more complex), that wouldn't be a
> problem, but as it calls it on any last insn and can actually do something
> in the bb, if such an insn is followed by one more more DEBUG_INSNs and
> nothing else in the same bb, we don't call purge_dead_edges with -g and do
> call it with -g0.
> 
> On the testcase, there are two reg-to-reg moves with REG_EH_REGION notes
> (previously memory accesses but simplified and yet not optimized), and the
> second is followed by DEBUG_INSNs; the second move is delete_insn_and_edges
> and after removing it, for -g0 purge_dead_edges removes the REG_EH_REGION
> from the now last insn in the bb (the first reg-to-reg move), while
> for -g it isn't called and things diverge from that quickly on.
> 
> Fixed by calling purdge_dead_edges even if we remove the last real insn
> followed only by DEBUG_INSNs in the same bb.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2020-04-17  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR rtl-optimization/94618
>       * cfgrtl.c (delete_insn_and_edges): Set purge not just when
>       insn is the BB_END of its block, but also when it is only followed
>       by DEBUG_INSNs in its block.
> 
>       * g++.dg/opt/pr94618.C: New test.
> 
> --- gcc/cfgrtl.c.jj   2020-01-12 11:54:36.218416351 +0100
> +++ gcc/cfgrtl.c      2020-04-16 17:28:00.792849169 +0200
> @@ -230,10 +230,20 @@ delete_insn_and_edges (rtx_insn *insn)
>  {
>    bool purge = false;
>  
> -  if (INSN_P (insn)
> -      && BLOCK_FOR_INSN (insn)
> -      && BB_END (BLOCK_FOR_INSN (insn)) == insn)
> -    purge = true;
> +  if (INSN_P (insn) && BLOCK_FOR_INSN (insn))
> +    {
> +      basic_block bb = BLOCK_FOR_INSN (insn);
> +      if (BB_END (bb) == insn)
> +     purge = true;
> +      else if (DEBUG_INSN_P (BB_END (bb)))
> +     for (rtx_insn *dinsn = NEXT_INSN (insn);
> +          DEBUG_INSN_P (dinsn); dinsn = NEXT_INSN (dinsn))
> +       if (BB_END (bb) == dinsn)
> +         {
> +           purge = true;
> +           break;
> +         }
> +    }
>    delete_insn (insn);
>    if (purge)
>      return purge_dead_edges (BLOCK_FOR_INSN (insn));
> --- gcc/testsuite/g++.dg/opt/pr94618.C.jj     2020-04-16 17:32:45.891637523 
> +0200
> +++ gcc/testsuite/g++.dg/opt/pr94618.C        2020-04-16 17:32:22.715979882 
> +0200
> @@ -0,0 +1,25 @@
> +// PR rtl-optimization/94618
> +// { dg-do compile { target c++11 } }
> +// { dg-options "-O2 -fnon-call-exceptions -fcompare-debug" }
> +
> +struct S
> +{
> +  int a, b, c;
> +  int foo () noexcept { return a; }
> +  int bar () noexcept { return b; }
> +  void baz (int);
> +  void qux () { if (c) for (int x = foo (); x != bar (); ) baz (x); }
> +};
> +
> +struct T
> +{
> +  S s;
> +  void foo ();
> +};
> +
> +void
> +T::foo ()
> +{
> +  s.qux ();
> +  s.qux ();
> +}
> 
>       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