tree-ssa-propagate: Special case lhs of musttail calls in may_propagate_copy [PR118430]
Checks
Commit Message
Hi!
And here is incremental (for now tested just on the new testcases)
patch to avoid VRP etc. to replace lhs of musttail call with something else.
2025-01-15 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.
Jakub
Comments
On Wed, 15 Jan 2025, Jakub Jelinek wrote:
> Hi!
>
> And here is incremental (for now tested just on the new testcases)
> patch to avoid VRP etc. to replace lhs of musttail call with something else.
OK.
Thanks,
Richard.
> 2025-01-15 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.
>
> --- gcc/tree-ssa-propagate.cc.jj 2025-01-02 11:23:02.000000000 +0100
> +++ gcc/tree-ssa-propagate.cc 2025-01-15 11:34:38.554602529 +0100
> @@ -870,7 +870,7 @@ substitute_and_fold_dom_walker::before_d
> }
> /* 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
> 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;
> }
> --- gcc/testsuite/c-c++-common/musttail14.c.jj 2025-01-15 11:32:58.048016223 +0100
> +++ gcc/testsuite/c-c++-common/musttail14.c 2025-01-15 11:33:30.982552975 +0100
> @@ -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)
>
> Jakub
>
>
@@ -870,7 +870,7 @@ substitute_and_fold_dom_walker::before_d
}
/* 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
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;
}
@@ -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)