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