Issue 129716
Summary Suboptimal codegen for vptr load
Labels new issue
Assignees
Reporter apolukhin
    Consider the example:
```cpp
#include <new>

struct Empty{};

template <class T>
struct UnionOptional {
 UnionOptional() = default;

    const T* set() {
        return ::new (&data_.payload) T();
    }

    void clear() {
 data_.payload.~T();
        data_.e = {};
    }

    union {
 Empty e{};
        T payload;
    } data_;
};

struct A {
    virtual void foo() const;
};

struct B : A {
    void foo() const override;
};

void sample_union() {
    UnionOptional<B> value;
 value.set()->foo();
    value.clear();
 value.set()->foo();
}
```

With -O2 or -O3 clang-19 generates the following assembly:
```
sample_union():
        push    r14
        push rbx
        push    rax
        mov     r14, qword ptr [rip + vtable for B@GOTPCREL]
        add     r14, 16
        mov     qword ptr [rsp], r14
 mov     rbx, rsp
        mov     rdi, rbx
        call    B::foo() const@PLT
        mov     qword ptr [rsp], r14
        mov     rdi, rbx
 call    B::foo() const@PLT
        add     rsp, 8
        pop rbx
        pop     r14
        ret
```
However, a more optimal assembly with less instructions and register clobbering could be used:
```
sample_union():
        sub     rsp, 24
        mov     QWORD PTR [rsp+8], OFFSET FLAT:vtable for B+16
        lea     rdi, [rsp+8]
 call    B::foo() const
        lea     rdi, [rsp+8]
        mov     QWORD PTR [rsp+8], OFFSET FLAT:vtable for B+16
        call    B::foo() const
 add     rsp, 24
        ret
```
Godbolt playground: https://godbolt.org/z/T5PzMfz1W
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to