]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ipa: Disallow signature changes in fun->has_musttail functions [PR121023]
authorJakub Jelinek <jakub@redhat.com>
Fri, 11 Jul 2025 10:09:44 +0000 (12:09 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Fri, 11 Jul 2025 10:09:44 +0000 (12:09 +0200)
As the following testcase shows e.g. on ia32, letting IPA opts change
signature of functions which have [[{gnu,clang}::musttail]] calls
can turn programs that would be compiled normally into something
that is rejected because the caller has fewer argument stack slots
than the function being tail called.

The following patch prevents signature changes for such functions.
It is perhaps too big hammer in some cases, but it might be hard
to try to figure out what signature changes are still acceptable and which
are not at IPA time.

2025-07-11  Jakub Jelinek  <jakub@redhat.com>
    Martin Jambor  <mjambor@suse.cz>

PR ipa/121023
* ipa-fnsummary.cc (compute_fn_summary): Disallow signature changes
on cfun->has_musttail functions.

* c-c++-common/musttail32.c: New test.

gcc/ipa-fnsummary.cc
gcc/testsuite/c-c++-common/musttail32.c [new file with mode: 0644]

index 48343a7696808f509ad25263ac5b5a66f7fe492d..924a54b498b77c2c6a48db45d7ea5ced381d8240 100644 (file)
@@ -3421,6 +3421,21 @@ compute_fn_summary (struct cgraph_node *node, bool early)
         info->inlinable = tree_inlinable_function_p (node->decl);
 
        bool no_signature = false;
+
+       /* Don't allow signature changes for functions which have
+         [[gnu::musttail]] or [[clang::musttail]] calls.  Sometimes
+         (more often on targets which pass everything on the stack)
+         signature changes can result in tail calls being impossible
+         even when without the signature changes they would be ok.
+         See PR121023.  */
+       if (cfun->has_musttail)
+        {
+          if (dump_file)
+           fprintf (dump_file, "No signature change:"
+                    " function has calls with musttail attribute.\n");
+          no_signature = true;
+        }
+
        /* Type attributes can use parameter indices to describe them.
          Special case fn spec since we can safely preserve them in
          modref summaries.  */
diff --git a/gcc/testsuite/c-c++-common/musttail32.c b/gcc/testsuite/c-c++-common/musttail32.c
new file mode 100644 (file)
index 0000000..f1b7052
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR ipa/121023 */
+/* { dg-do compile { target musttail } } */
+/* { dg-options "-O2" } */
+
+struct S { int a, b; };
+
+[[gnu::noipa]] int
+foo (struct S x, int y, int z)
+{
+  return x.a + y + z;
+}
+
+[[gnu::noinline]] static int
+bar (struct S x, int y, int z)
+{
+  [[gnu::musttail]] return foo ((struct S) { x.a, 0 }, y, 1);
+}
+
+int
+baz (int x)
+{
+  return bar ((struct S) { 1, 2 }, x, 2) + bar ((struct S) { 2, 3 }, x + 1, 2);
+}