--- /dev/null
+/* PR tree-optimization/119493 */
+/* { dg-do compile { target musttail } } */
+/* { dg-options "-O2 -fdump-tree-tailr1-details" } */
+/* { dg-final { scan-tree-dump-times "tail recursion with accumulation mixed with musttail non-recursive call" 2 "tailr1" } } */
+
+[[gnu::noipa]] int
+bar (int x, int y)
+{
+ return x + y;
+}
+
+[[gnu::noinline, gnu::noclone]] int
+foo (int x, int y)
+{
+ if (x < 10)
+ [[gnu::musttail]] return bar (x, y);
+ if (y & 2)
+ return foo (x - 1, y) * 2;
+ if (y & 1)
+ [[gnu::musttail]] return foo (x - 1, y);
+ return foo (x - 1, y) * 3;
+}
live_vars = NULL;
}
+ if (cfun->has_musttail)
+ {
+ /* We can't mix non-recursive must tail calls with tail recursive
+ calls which require accumulators, because in that case we have to
+ emit code in between the musttail calls and return, which prevent
+ calling them as tail calls. So, in that case give up on the
+ tail recursion. */
+ for (act = tailcalls; act; act = act->next)
+ if (!act->tail_recursion)
+ {
+ gcall *call = as_a <gcall *> (gsi_stmt (act->call_gsi));
+ if (gimple_call_must_tail_p (call))
+ break;
+ }
+ if (act)
+ for (struct tailcall **p = &tailcalls; *p; )
+ {
+ if ((*p)->tail_recursion && ((*p)->add || (*p)->mult))
+ {
+ struct tailcall *a = *p;
+ *p = (*p)->next;
+ gcall *call = as_a <gcall *> (gsi_stmt (a->call_gsi));
+ maybe_error_musttail (call,
+ _("tail recursion with accumulation "
+ "mixed with musttail "
+ "non-recursive call"), diag_musttail);
+ free (a);
+ }
+ else
+ p = &(*p)->next;
+ }
+ }
/* Construct the phi nodes and accumulators if necessary. */
a_acc = m_acc = NULL_TREE;
for (act = tailcalls; act; act = act->next)