As the following testcase shows, sometimes we can have debug stmts
after a musttail call and profile.cc in that case would incorrectly
allow the edge from that, causing musttail error and -fcompare-debug
failure (because if there are no debug stmts after it, then musttail
is found there and the edge is ignored).
The following patch uses gsi_last_nondebug_bb instead of gsi_last_bb
to find the musttail call. And so that we don't uselessly skip over
debug stmts at the end of many bbs, the patch limits it to
cfun->has_musttail functions.
2025-04-04 Jakub Jelinek <jakub@redhat.com>
PR gcov-profile/119618
* profile.cc (branch_prob): Only check for musttail calls if
cfun->has_musttail. Use gsi_last_nondebug_bb instead of gsi_last_bb.
* c-c++-common/pr119618.c: New test.
ignored_edges++;
}
/* Ignore edges after musttail calls. */
- if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
+ if (cfun->has_musttail
+ && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
{
- gimple_stmt_iterator gsi = gsi_last_bb (e->src);
+ gimple_stmt_iterator gsi = gsi_last_nondebug_bb (e->src);
gimple *stmt = gsi_stmt (gsi);
if (stmt
&& is_gimple_call (stmt)
--- /dev/null
+/* PR gcov-profile/119618 */
+/* { dg-do compile { target musttail } } */
+/* { dg-options "-fcompare-debug -fprofile-generate -O1" } */
+/* { dg-require-profiling "-fprofile-generate" } */
+
+struct S { char s; };
+int foo (void);
+int *(*fn) (void);
+
+int *
+bar (void)
+{
+ if (foo ())
+ return 0;
+ {
+ struct S s;
+ do
+ [[gnu::musttail]] return fn ();
+ while (0);
+ }
+}