Issue 163811
Summary Missed tail call optimization in branch
Labels new issue
Assignees
Reporter rockeet
    ```c++
struct C {
    int x;
 //~C();
};
bool foo();
void bar();
C C_get_impl();
C C_get() {
 return C_get_impl(); // OK, both gcc & clang tail call
}
C C_get_cond() {
 if (__builtin_expect(foo(), 1)) {
        return C_get_impl(); // gcc tail call, clang missed
    } else {
        C r = C_get_impl();
 bar();
        return r;
    }
}
struct D {
    int x;
    ~D(); // has destructor
};
D D_get_impl();
D D_get() {
    return D_get_impl(); // clang tail call, gcc missed
}
D D_get_cond() {
    if (__builtin_expect(foo(), 1)) {
        return D_get_impl(); // both gcc & clang missed tail call
    } else {
        D r = D_get_impl();
 bar();
        return r;
    }
}
```
clang(trunk) generate code(https://godbolt.org/z/T7hxThzax):
```asm
C_get():
        jmp C_get_impl()@PLT

C_get_cond():
        push    rbx
        call foo()@PLT
        mov     ebx, eax
        call    C_get_impl()@PLT
 test    bl, bl
        je      .LBB1_1
        pop     rbx
 ret
.LBB1_1:
        mov     ebx, eax
        call    bar()@PLT
 mov     eax, ebx
        pop     rbx
        ret

D_get():
        jmp D_get_impl()@PLT

D_get_cond():
        push    rbp
        push r14
        push    rbx
        mov     rbx, rdi
        call foo()@PLT
        mov     ebp, eax
        mov     rdi, rbx
        call D_get_impl()@PLT
        test    bpl, bpl
        je .LBB3_1
.LBB3_2:
        mov     rax, rbx
        pop     rbx
        pop r14
        pop     rbp
        ret
.LBB3_1:
        call bar()@PLT
        jmp     .LBB3_2
        mov     r14, rax
        mov rdi, rbx
        call    D::~D()@PLT
        mov     rdi, r14
        call _Unwind_Resume@PLT

DW.ref.__gxx_personality_v0:
        .quad __gxx_personality_v0
```
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to