> Am 04.04.2025 um 19:25 schrieb Jakub Jelinek <ja...@redhat.com>:
> 
> Hi!
> 
> In PR119491 r15-9154 I've allowed some useless EH regions for musttail
> calls (if there are no non-debug/clobber stmts before resx which resumes
> external throwing).
> Now, for -O1+ (but not -O0/-Og) there is a cleanup_eh pass after it
> which should optimize that way.
> The following testcase ICEs at -O0 though, the cleanup_eh in that case
> is before the musttail pass and dunno why it didn't actually optimize
> it away.
> 
> The following patch catches that during expansion and just removes the note,
> which causes EH cleanups to do the rest.  A tail call, even when it throws,
> will not throw while the musttail caller's frame is still on the stack,
> will throw after that and so REG_EH_REGION for it is irrelevant (like it
> would be never set before the r15-9154 changes).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok

Richard 

> 
> 2025-04-04  Jakub Jelinek  <ja...@redhat.com>
> 
>    PR middle-end/119613
>    * cfgrtl.cc (purge_dead_edges): Remove REG_EH_REGION notes from
>    tail calls.
> 
>    * g++.dg/opt/pr119613.C: New test.
> 
> --- gcc/cfgrtl.cc.jj    2025-02-13 19:59:55.165577958 +0100
> +++ gcc/cfgrtl.cc    2025-04-04 09:17:16.309666732 +0200
> @@ -3213,6 +3213,16 @@ purge_dead_edges (basic_block bb)
>          && ! may_trap_p (XEXP (eqnote, 0))))
>    remove_note (insn, note);
>     }
> +  /* A tail call cannot trap either.  The tailc/musttail pass could have
> +     allowed a tail call if it could throw internally, but perform no
> +     actual statements and then caused the exception to be thrown externally
> +     in the hope that it is cleaned up later.  If it is not, just
> +     remove REG_EH_REGION note.  While the call maybe can throw, the
> +     current function's frame will not be there anymore when it does.  */
> +   if (CALL_P (insn)
> +       && SIBLING_CALL_P (insn)
> +       && (note = find_reg_note (insn, REG_EH_REGION, NULL)))
> +     remove_note (insn, note);
> 
>   /* Cleanup abnormal edges caused by exceptions or non-local gotos.  */
>   for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); )
> --- gcc/testsuite/g++.dg/opt/pr119613.C.jj    2025-04-04 09:16:56.867680864 
> +0200
> +++ gcc/testsuite/g++.dg/opt/pr119613.C    2025-04-04 09:18:24.541617133 +0200
> @@ -0,0 +1,22 @@
> +// PR middle-end/119613
> +// { dg-do compile { target { musttail && { c || c++11 } } } }
> +// { dg-options "-O0" }
> +
> +struct S { S () {} };
> +char *foo (S);
> +void bar (int);
> +
> +[[gnu::always_inline]] inline char *
> +baz (S x)
> +{
> +  unsigned i;
> +  &i;
> +  bar (i);
> +  [[gnu::musttail]] return foo (x);
> +}
> +
> +char *
> +qux (S)
> +{
> +  [[gnu::musttail]] return baz (S {});
> +}
> 
>    Jakub
> 

Reply via email to