On Thu, Mar 20, 2025 at 10:02 AM Andi Kleen <a...@firstfloor.org> wrote: > > On Thu, Mar 20, 2025 at 05:28:48PM +0100, Jakub Jelinek wrote: > > On Thu, Mar 20, 2025 at 09:19:02AM -0700, Andi Kleen wrote: > > > The inlining was just one of the issue, there are some related to > > > different semantics of escaped locals. gcc always errors out while > > > LLVM declares it undefined. > > > > > > But maybe we can fix that one too. > > > > I have 3 patches to be tested, the inline one, fnsplit one and ipa-icf one. > > For the escaped locals, I guess we need to decide if [[clang::musttail]] > > will be something different from [[gnu::musttail]] in GCC or not (and if > > yes, what __attribute__((musttail)) will be). > > There were more differences. clang is better to handle various > cases with structs at -O0 and then there are some target specific differences > too (e.g. some of our targets always reject externs) > > But maybe it's good enough. > > I don't think multiple flavors of musttail are a good idea because > it will be confusing to users. I guess we should just match what clang does > even for gnu::musttail. Since they were the pioneer they get to chose > the semantics. > > > > The current difference in behavior is on > > int foo (void); > > void bar (int *); > > int > > baz (void) > > { > > int a; > > bar (&a); > > [[clang::musttail]] return foo (); > > } > > Clang makes the attribute not just a request to tail call it or fail, > > but also changes behavior and says if the code ever accesses a from the > > above during foo () (which without the attribute is completely valid), then > > it is UB. > > > So it could be as simple as that patch? It solves your test case at least > for x86. > > diff --git a/gcc/tree-tailcall.cc b/gcc/tree-tailcall.cc > index f97df31eb3cf..b87a92e95e3d 100644 > --- a/gcc/tree-tailcall.cc > +++ b/gcc/tree-tailcall.cc > @@ -722,8 +722,9 @@ find_tail_calls (basic_block bb, struct tailcall **ret, > bool only_musttail, > { > if (local_live_vars) > BITMAP_FREE (local_live_vars); > - maybe_error_musttail (call, > - _("call invocation refers to locals")); > + /* Allow this for musttail to match clang semantics of > musttail. */ > + if (gimple_call_must_tail_p (call)) > + continue;
It still would be a good thing to have a debug dump for this case. Maybe even a warning. Plus take: ``` int foo (int*); void bar (int *); int baz (int*) { int a; bar (&a); int *b = &a; [[clang::musttail]] return foo (b); } int baz1 (int*) { int a; bar (&a); [[clang::musttail]] return foo (&a); } ``` Note clang warns about baz1 and at this point GCC should be able to warn about both cases too. Thanks, Andrew Pinski > return; > } > else > @@ -732,8 +733,9 @@ find_tail_calls (basic_block bb, struct tailcall **ret, > bool only_musttail, > if (bitmap_bit_p (local_live_vars, *v)) > { > BITMAP_FREE (local_live_vars); > - maybe_error_musttail (call, > - _("call invocation refers to > locals")); > + /* Allow this for musttail to match clang semantics of > musttail. */ > + if (gimple_call_must_tail_p (call)) > + continue; > return; > } > }