https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71761
Konstantin Kharlamov <Hi-Angel at yandex dot ru> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |Hi-Angel at yandex dot ru --- Comment #4 from Konstantin Kharlamov <Hi-Angel at yandex dot ru> --- (In reply to Marc Glisse from comment #3) > For clang, this seems based on size: up to size 16 they get jmp, starting > from 17 they get a call. > > For gcc, we give up on anything more complicated than a "register": > > /* If the LHS of our call is not just a simple register, we can't > transform this into a tail or sibling call. This situation happens, > in (e.g.) "*p = foo()" where foo returns a struct. In this case > we won't have a temporary here, but we need to carry out the side > effect anyway, so tailcall is impossible. > > ??? In some situations (when the struct is returned in memory via > invisible argument) we could deal with this, e.g. by passing 'p' > itself as that argument to foo, but it's too early to do this here, > and expand_call() will not handle it anyway. If it ever can, then > we need to revisit this here, to allow that situation. */ > if (ass_var && !is_gimple_reg (ass_var)) > return; > > The ??? comment is exactly your case. So this means, if I dump GIMPLE, I should see something wrong, right? When I do this, given a file named test.cpp and I use `-fdump-tree-all`, the whole GIMPLE I see in file `test.cpp.231t.optimized` is this: ;; Function g (_Z1gv, funcdef_no=0, decl_uid=2305, cgraph_uid=1, symbol_order=0) g () { <bb 2> [local count: 1073741824]: # DEBUG BEGIN_STMT <retval> = f (); [return slot optimization] [tail call] return <retval>; } ;; Function main (main, funcdef_no=1, decl_uid=2341, cgraph_uid=2, symbol_order=1) (executed once) main () { struct token D.2343; <bb 2> [local count: 1073741824]: # DEBUG BEGIN_STMT # DEBUG INLINE_ENTRY g # DEBUG BEGIN_STMT D.2343 = f (); [return slot optimization] D.2343 ={v} {CLOBBER}; return 0; } What should I see? Should there be a `goto f` inside `g()` function, or what?