<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">