]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
profile: Don't instrument fake exit edges after musttail [PR118442]
authorJakub Jelinek <jakub@redhat.com>
Wed, 26 Mar 2025 12:59:16 +0000 (13:59 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 26 Mar 2025 12:59:16 +0000 (13:59 +0100)
When -fprofile-generate is used musttail often fails because the
compiler adds instrumentation after the tail calls.

This patch ignores EDGE_FAKE edges added from musttail calls to EXIT.

2025-03-26  Jakub Jelinek  <jakub@redhat.com>
    Andi Kleen  <ak@gcc.gnu.org>

PR gcov-profile/118442
* profile.cc (branch_prob): Ignore EDGE_FAKE edges from musttail calls
to EXIT.

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

gcc/profile.cc
gcc/testsuite/c-c++-common/pr118442.c [new file with mode: 0644]

index acc0ae0cc201ea80730974228626cdee3d49f40b..76fed352f00a5783f4fe675ae3d07c40d8fe75e1 100644 (file)
@@ -1340,6 +1340,20 @@ branch_prob (bool thunk)
          EDGE_INFO (e)->ignore = 1;
          ignored_edges++;
        }
+      /* Ignore fake edges after musttail calls.  */
+      if ((e->flags & EDGE_FAKE)
+         && e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
+       {
+         gimple_stmt_iterator gsi = gsi_last_bb (e->src);
+         gimple *stmt = gsi_stmt (gsi);
+         if (stmt
+             && is_gimple_call (stmt)
+             && gimple_call_must_tail_p (as_a <const gcall *> (stmt)))
+           {
+             EDGE_INFO (e)->ignore = 1;
+             ignored_edges++;
+           }
+       }
     }
 
   /* Create spanning tree from basic block graph, mark each edge that is
diff --git a/gcc/testsuite/c-c++-common/pr118442.c b/gcc/testsuite/c-c++-common/pr118442.c
new file mode 100644 (file)
index 0000000..2472aa6
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR118442 */
+/* { dg-do compile { target { struct_musttail && { external_musttail && { c || c++11 } } } } } */
+/* { dg-options "-fprofile-generate -O2" } */
+/* { dg-require-profiling "-fprofile-generate" } */
+
+struct Span {
+  int test[5];
+};
+
+extern void resolveToBufferSlow (struct Span *buffer);
+
+void
+resolveToBuffer (struct Span *buffer)
+{
+  buffer->test[0] = 4;
+  [[clang::musttail]] return resolveToBufferSlow (buffer);
+}