As the following testcase shows, EDGE_FAKE edges from musttail calls to
EXIT aren't the only edges we should ignore, we need to ignore also
edges created by the splitting of blocks for the EDGE_FAKE creation that
point from the musttail calls to the fallthrough block, which typically does
the return or with PHIs for the return value.
2025-04-01 Jakub Jelinek <jakub@redhat.com>
PR gcov-profile/119535
* profile.cc (branch_prob): Ignore any edges from bbs ending with
musttail call, rather than only EDGE_FAKE edges from those to EXIT.
* c-c++-common/pr119535.c: New test.
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))
+ /* Ignore edges after musttail calls. */
+ if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
{
gimple_stmt_iterator gsi = gsi_last_bb (e->src);
gimple *stmt = gsi_stmt (gsi);
--- /dev/null
+/* PR gcov-profile/119535
+/* { dg-do compile { target musttail } } */
+/* { dg-options "-fprofile-generate -O2" } */
+/* { dg-require-profiling "-fprofile-generate" } */
+
+[[gnu::noipa]] int
+foo (int x)
+{
+ return 42 + x;
+}
+
+int
+bar (int x)
+{
+ foo (x);
+ foo (2);
+ [[clang::musttail]] return foo (3);
+}
+
+int
+baz (int x)
+{
+ if (x == 42)
+ return -1;
+ else if (x == 15)
+ return 25;
+ else if (x == 26)
+ [[clang::musttail]] return foo (4);
+ else
+ [[clang::musttail]] return foo (5);
+}