https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120833
Bug ID: 120833 Summary: gcc does not recognize tail calls Product: gcc Version: 16.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: rockeet at gmail dot com Target Milestone: --- struct S1 { const char* data; long size; }; struct S2 { const char* data; long size; }; __attribute__((noinline)) struct S1 get_s1(const char* s, long n) { struct S1 x; x.data = s; x.size = n; return x; } struct S1 get_s1_wrap(const char* s, long n) { return get_s1(s, n); } struct S2 get_s2(const char* s, long n) { struct S1 x = get_s1(s, n); struct S2 y = {x.data, x.size}; return y; } struct S2 get_s2_2(const char* s, long n) { struct S1 x = get_s1(s, n); return *(struct S2*)&x; } the newest gcc & g++ generate code: "get_s1": mov rax, rdi mov rdx, rsi ret "get_s1_wrap": jmp "get_s1" "get_s2": sub rsp, 8 call "get_s1" add rsp, 8 ret "get_s2_2": sub rsp, 8 call "get_s1" add rsp, 8 ret gcc does not recognize get_s2 & get_s2 are tail calls. clang generate ideal code at very old version(clang-3.0): get_s1: # @get_s1 mov RAX, RDI mov RDX, RSI ret get_s1_wrap: # @get_s1_wrap jmp get_s1 # TAILCALL get_s2: # @get_s2 jmp get_s1 # TAILCALL get_s2_2: # @get_s2_2 jmp get_s1 # TAILCALL