<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/129716>129716</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            Suboptimal codegen for vptr load
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          apolukhin
      </td>
    </tr>
</table>

<pre>
    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
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJy0VkFz4jgT_TXi0gVly0Dg4AMmMN8hX5HNsJXjlGw1RruypZVkk-Swv31LtmFsYGcmh1WlykHqft393lPZzFqRl4gxmSVk9jhilTsqEzOtZPXnUZSjVPH3eK1KKzgacEcEfGOFlkiiFQlWZB60f5nW_ieNRJnJiiOQaF3iiUQbvx2srDNV5mBTaPdOHhLy8EiipD1yWGjJXJOSSWYt7Nu0Luf3Uqhyp51QJZPgk4PVcJPQBaFLINEjcDywSroLOABApkrrYE_oCiy6c3CL0y2DrjIl-KGiVYknaKLmnDn2baLZu1SM-6x9m93C-0Q_yKVQrQSHTCIzwyIDmMnfNyB-tTHYDNEn6KZI5Sc_Izd8Al4n-LWHc999nLZOR09PhI7rVY-XWhhXMdlOdVCqm6lh818BEs_hEOZOOqgajREcb3GacNtY7Fsz6o1eQ-mjdUKiDdRMVh1a-__kIvWYRJtL_e9ktFE9tX45u5PjbP2271fhjjDeUVAGxrsIMsnKfBwuIccSDXNom9tzUFKqkyhzYNZikcr3q4vkqbyZvo05K6sre2xMG06vd036di-Q9XcLVcM5na7hr5MyHLQzQGaJERoITaB2LJW-WwMJmQZfdvvn9cvmicwee0CM8z5QOL9TZIhutUeg63Prl1bSt2bX6nt9ctEcDkbLmJT-mbRX9tqe0-D5af_pdn5Y-JMVL-RY7UEWfVmUvhZKabhV1KC7csb_1AlrNB6QQaEMgtJOFExe3AQn70OJ1oIo2zspVGmBlRwM5sI6NJBJlaZovAszVUkOKUJlkX_eirZK-1PSezT-9rp7eYTn_cuZc5osOt532-3XzR62T6s9iVYD09Fk4CeJrK_JEOnn6vw60H_R_M-bu3IL_bENviieKulAS_aeG1WVXjk4Oqetr0C3hG7zNmaiTE7o9oPQ7X72_PH_w0f4OuJxxJfRko0wDh-mYbBcLkI6OsYsxWV6mLHD8pDRLJynfL6cY7QIo3kWHWaHkYhpQGdBFEzD6SwI6YSnDwc2XzC-YJxxviDTAAsm5ETKuvC1R8LaCuOQLh_C-UiyFKVtPjYo9a_Z5pRQ6r89TOyTxmmVWzINpLDOfodxwkmMv1bp2fCZ4phj2RBe-wvtX3Wjysj4igfhjlU6yVRB6NbDdY-xNuoPzByh26YJS-i267KO6T8BAAD__yFfi6E">