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

Reply via email to