]> git.ipfire.org Git - thirdparty/gcc.git/commit
tailc: Only diagnose musttail failures during tailc or musttail passes [PR119376]
authorJakub Jelinek <jakub@redhat.com>
Tue, 25 Mar 2025 08:36:41 +0000 (09:36 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 25 Mar 2025 08:36:41 +0000 (09:36 +0100)
commit698e337bec3a36230c72816fcb82f1a239e64eba
tree57e51d7efbbc4393f3c1c6385b76b4e2279cbc35
parent127a24ede2f82eafecb5eb142e21dbda38d06c18
tailc: Only diagnose musttail failures during tailc or musttail passes [PR119376]

The following testcases FAIL because musttail failures are diagnosed
not just in the tailc or musttail passes, but also during the tailr1
and tailr2.
tailr1 pass is before IPA and in the testcases eh cleanup has not
cleaned up the IL sufficiently yet to make the musttail calls pass,
even tailr2 could be too early.

The following patch does that only during the tailc pass, and if that
pass is not actually executed, during musttail pass.
To do it only in the tailc pass, I chose to pass a new bool flag, because
while we have the opt_tailcalls argument, it is actually passed by reference
to find_tail_calls and sometimes cleared during that.
musttail calls when the new DIAG_MUSTTAIL flag is not set are handled like
any other calls, we simply silently punt on those if they can't be turned
into tail calls.

Furthermore, I had to tweak the musttail pass gate.  Previously it was
!flag_optimize_sibling_calls && f->has_musttail.  The problem is that
gate of tailr and tailc passes is
flag_optimize_sibling_calls != 0 && dbg_cnt (tail_call)
and furthermore, tailc pass is only in the normal optimization queue,
so only if not -O0 or -Og.  So when one would use tail_call dbg_cnt
with some limit, or when e.g. using -foptimize-sibling-calls with -O0 or
-Og, nothing would actually diagnose invalid musttail calls or set tail call
flags on those if they are ok.  I could insert a new PROP_ flag on whether
musttail has been handled by tailc pass, but given that we have the
cfun->has_musttail flag already and nothing after tailc/musttail passes uses
it, I think it is easier to just clear the flag when musttail failures are
diagnosed and correct ones have [[tail call]] flag added.  Expansion will
then only look at the [[tail call]] flag, it could even at the [[must tail
call]] flag, but I don't see a point to check cfun->has_musttail.

2025-03-25  Jakub Jelinek  <jakub@redhat.com>

PR ipa/119376
* tree-tailcall.cc (suitable_for_tail_opt_p): Add DIAG_MUSTTAIL
argument, propagate it down to maybe_error_musttail.
(suitable_for_tail_call_opt_p): Likewise.
(maybe_error_musttail): Add DIAG_MUSTTAIL argument.  Don't emit error
for gimple_call_must_tail_p calls if it is false.
(find_tail_calls): Add DIAG_MUSTTAIL argument, propagate it down to
maybe_error_musttail, suitable_for_tail_opt_p,
suitable_for_tail_call_opt_p and find_tail_calls calls.
(tree_optimize_tail_calls_1): Add DIAG_MUSTTAIL argument, propagate
it down to find_tail_calls and if set, clear cfun->has_musttail flag
at the end.  Rename OPT_MUSTCALL argument to OPT_MUSTTAIL.
(execute_tail_calls): Pass true to DIAG_MUSTTAIL
tree_optimize_tail_calls_1 argument.
(pass_tail_recursion::execute): Pass false to DIAG_MUSTTAIL
tree_optimize_tail_calls_1 argument.
(pass_musttail::gate): Don't test flag_optimize_sibling_calls.
(pass_musttail::execute): Pass true to DIAG_MUSTTAIL
tree_optimize_tail_calls_1 argument.

* g++.dg/torture/musttail1.C: New test.
* g++.dg/opt/musttail2.C: New test.
gcc/testsuite/g++.dg/opt/musttail2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/torture/musttail1.C [new file with mode: 0644]
gcc/tree-tailcall.cc