> 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
>