aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-01-16 09:25:16 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2025-01-16 09:27:54 +0100
commit7f5adfd31b3af08924faec36679eaea40a98af19 (patch)
tree54fc4cc2847cb1516fbad20a4f41888d4468aab6
parent9c4397cafc5ded9b008a92a55d4e5207e1c2e4e4 (diff)
downloadgcc-7f5adfd31b3af08924faec36679eaea40a98af19.zip
gcc-7f5adfd31b3af08924faec36679eaea40a98af19.tar.gz
gcc-7f5adfd31b3af08924faec36679eaea40a98af19.tar.bz2
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 <jakub@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.
-rw-r--r--gcc/testsuite/c-c++-common/musttail14.c6
-rw-r--r--gcc/tree-ssa-propagate.cc9
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 e2ab20b..e95bc9b 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 94d4401..ec20689 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;
}