On Fri, 21 Mar 2025, Jakub Jelinek wrote: > Hi! > > The following testcase shows we were ignoring musttail flags on calls > when deciding if two functions are the same. > That can result in problems in both directions, either we silently > lose musttail attribute because there is a similar function without it > earlier and then we e.g. don't diagnose if it can't be tail called > or don't try harder to do a tail call, or we get it even in functions > which didn't have it before. > > The following patch for now just punts if it differs. Perhaps we could > just merge it and get musttail flag if any of the merged functions had > one in such position, but it feels to me that it is now too late in GCC 15 > cycle to play with this. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Richard. > 2025-03-20 Jakub Jelinek <ja...@redhat.com> > > PR ipa/119376 > * ipa-icf-gimple.cc (func_checker::compare_gimple_call): Return false > for gimple_call_must_tail_p mismatches. > > * c-c++-common/musttail27.c: New test. > > --- gcc/ipa-icf-gimple.cc.jj 2025-02-27 22:04:06.082435026 +0100 > +++ gcc/ipa-icf-gimple.cc 2025-03-20 15:33:38.996614656 +0100 > @@ -708,7 +708,8 @@ func_checker::compare_gimple_call (gcall > || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2) > || gimple_call_from_new_or_delete (s1) != > gimple_call_from_new_or_delete (s2) > || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2) > - || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p > (s2)) > + || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p > (s2) > + || gimple_call_must_tail_p (s1) != gimple_call_must_tail_p (s2)) > return false; > > unsigned check_arg_types_from = 0; > --- gcc/testsuite/c-c++-common/musttail27.c.jj 2025-03-20 > 15:42:30.200261715 +0100 > +++ gcc/testsuite/c-c++-common/musttail27.c 2025-03-20 15:44:24.990674296 > +0100 > @@ -0,0 +1,31 @@ > +/* PR ipa/119376 */ > +/* { dg-do compile { target musttail } } */ > +/* { dg-options "-O2 -fdump-tree-optimized" } */ > +/* { dg-final { scan-tree-dump-times " \[^\n\r]* = foo \\\(\[^\n\r]*\\\); > \\\[tail call\\\] \\\[must tail call\\\]" 2 "optimized" } } */ > +/* { dg-final { scan-tree-dump-times " \[^\n\r]* = foo \\\(\[^\n\r]*\\\); > \\\[tail call\\\]" 4 "optimized" } } */ > + > +int foo (int); > + > +int > +bar (int x) > +{ > + [[gnu::musttail]] return foo (x + 1); > +} > + > +int > +baz (int x) > +{ > + return foo (x + 1); > +} > + > +int > +qux (int x) > +{ > + return foo (x + 2); > +} > + > +int > +corge (int x) > +{ > + [[gnu::musttail]] return foo (x + 2); > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg, Germany; GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)