https://gcc.gnu.org/g:7f5adfd31b3af08924faec36679eaea40a98af19
commit r15-6944-g7f5adfd31b3af08924faec36679eaea40a98af19 Author: Jakub Jelinek <ja...@redhat.com> Date: Thu Jan 16 09:25:16 2025 +0100 tree-ssa-propagate: Special case lhs of musttail calls in may_propagate_copy [PR118430] This patch ensures that VRP or similar passes don't replace the uses of lhs of [[gnu::musttail]] calls with some constant (e.g. if the call is known is known to return a singleton value range) etc. to make it more likely that it is actually tail callable. 2025-01-16 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/118430 * tree-ssa-propagate.cc (may_propagate_copy): Return false if dest is lhs of an [[gnu::musttail]] call. (substitute_and_fold_dom_walker::before_dom_children): Formatting fix. * c-c++-common/musttail14.c: Expect lhs on the must tail call calls. Diff: --- gcc/testsuite/c-c++-common/musttail14.c | 6 +++--- gcc/tree-ssa-propagate.cc | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/gcc/testsuite/c-c++-common/musttail14.c b/gcc/testsuite/c-c++-common/musttail14.c index e2ab20bc5a46..e95bc9bc7688 100644 --- a/gcc/testsuite/c-c++-common/musttail14.c +++ b/gcc/testsuite/c-c++-common/musttail14.c @@ -1,9 +1,9 @@ /* PR tree-optimization/118430 */ /* { dg-do compile { target musttail } } */ /* { dg-options "-O2 -fdump-tree-optimized" } */ -/* { dg-final { scan-tree-dump-times " bar \\\(\[^\n\r]\*\\\); \\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */ -/* { dg-final { scan-tree-dump-times " freddy \\\(\[^\n\r]\*\\\); \\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */ -/* { dg-final { scan-tree-dump-times " (?:bar|freddy) \\\(\[^\n\r]\*\\\); \\\[tail call\\\]" 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \[^\n\r]* = bar \\\(\[^\n\r]\*\\\); \\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \[^\n\r]* = freddy \\\(\[^\n\r]\*\\\); \\\[tail call\\\] \\\[must tail call\\\]" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-not " (?:bar|freddy) \\\(\[^\n\r]\*\\\); \\\[tail call\\\]" "optimized" } } */ __attribute__ ((noipa)) void foo (int x) diff --git a/gcc/tree-ssa-propagate.cc b/gcc/tree-ssa-propagate.cc index 94d4401f54af..ec2068948215 100644 --- a/gcc/tree-ssa-propagate.cc +++ b/gcc/tree-ssa-propagate.cc @@ -870,7 +870,7 @@ substitute_and_fold_dom_walker::before_dom_children (basic_block bb) } /* Also fold if we want to fold all statements. */ else if (substitute_and_fold_engine->fold_all_stmts - && fold_stmt (&i, follow_single_use_edges)) + && fold_stmt (&i, follow_single_use_edges)) { did_replace = true; stmt = gsi_stmt (i); @@ -1081,6 +1081,13 @@ may_propagate_copy (tree dest, tree orig, bool dest_not_abnormal_phi_edge_p) if (TREE_CODE (dest) == SSA_NAME && virtual_operand_p (dest)) return false; + /* Keep lhs of [[gnu::musttail]] calls as is, those need to be still + tail callable. */ + if (TREE_CODE (dest) == SSA_NAME + && is_gimple_call (SSA_NAME_DEF_STMT (dest)) + && gimple_call_must_tail_p (as_a <gcall *> (SSA_NAME_DEF_STMT (dest)))) + return false; + /* Anything else is OK. */ return true; }