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