aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-03-21 12:17:45 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2025-03-21 12:17:45 +0100
commit589c94da22ec71fe8518878e801e88b05deffe18 (patch)
treec5cc9390acb85e6608d5c7cf4ec8710aaffbbf4b /gcc
parent37ae2e055687a22974d7bcb9e618f258fa49ab1a (diff)
downloadgcc-589c94da22ec71fe8518878e801e88b05deffe18.zip
gcc-589c94da22ec71fe8518878e801e88b05deffe18.tar.gz
gcc-589c94da22ec71fe8518878e801e88b05deffe18.tar.bz2
fnsplit: Set musttail call during function splitting if there are musttail calls [PR119376]
The just posted inliner patch can regress musttail calls if we perform function splitting and then inline the outlined body back into the original (or inline both the small function and outlined large body into something else). If there are any musttail calls, I think we need to call the outlined body using a musttail call, so that the inliner will preserve musttail attributes in the body. 2025-03-21 Jakub Jelinek <jakub@redhat.com> PR ipa/119376 * ipa-split.cc (split_function): Call gimple_call_set_must_tail on the call to outlined partition if has_musttail and !add_tsan_func_exit. * g++.dg/opt/musttail1.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ipa-split.cc2
-rw-r--r--gcc/testsuite/g++.dg/opt/musttail1.C35
2 files changed, 37 insertions, 0 deletions
diff --git a/gcc/ipa-split.cc b/gcc/ipa-split.cc
index ff562e2a..729fb79 100644
--- a/gcc/ipa-split.cc
+++ b/gcc/ipa-split.cc
@@ -1473,6 +1473,8 @@ split_function (basic_block return_bb, class split_point *split_point,
args_to_pass[i] = arg;
}
call = gimple_build_call_vec (node->decl, args_to_pass);
+ if (cur_node->get_fun ()->has_musttail && !add_tsan_func_exit)
+ gimple_call_set_must_tail (call, true);
gimple_set_block (call, DECL_INITIAL (current_function_decl));
args_to_pass.release ();
diff --git a/gcc/testsuite/g++.dg/opt/musttail1.C b/gcc/testsuite/g++.dg/opt/musttail1.C
new file mode 100644
index 0000000..5fe8ab6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/musttail1.C
@@ -0,0 +1,35 @@
+// PR ipa/119376
+// { dg-do compile { target musttail } }
+// { dg-options "-O2 -fdump-tree-optimized" }
+// { dg-final { scan-tree-dump-times " \[^\n\r]* = foo \\\(\[^\n\r]*\\\); \\\[tail call\\\] \\\[must tail call\\\]" 2 "optimized" } }
+// { dg-final { scan-tree-dump-times " \[^\n\r]* = foo \\\(\[^\n\r]*\\\); \\\[tail call\\\]" 3 "optimized" } }
+
+int foo (int x);
+typedef int (*F) (int);
+int v;
+
+inline int
+bar (int x)
+{
+ if (__builtin_expect (x == 42, 1))
+ return 1;
+ [[gnu::musttail]] return foo (x + v * (x | v) * (x & v) * (x - v) * (x + v * v));
+}
+
+int
+baz (int x)
+{
+ [[gnu::musttail]] return bar (x);
+}
+
+int
+qux (int x)
+{
+ return bar (x + 1);
+}
+
+F
+corge ()
+{
+ return &bar;
+}