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

Reply via email to