Closed
Description
https://godbolt.org/z/jEM7nrKhs
With the following code
struct A {
int type;
};
struct B : A {
int value;
};
struct C : A {
int value;
int value2;
};
int foo(A *p) {
if (p->type == 0) [[likely]] return static_cast<B*>(p)->value;
return static_cast<C*>(p)->value;
}
int bar(A *p) {
if (p->type == 0) [[unlikely]] return static_cast<B*>(p)->value;
return static_cast<C*>(p)->value;
}
int zeta(A *p) {
if (p->type == 0) return static_cast<B*>(p)->value;
return static_cast<C*>(p)->value;
}
The offset of B::value
and C::value
are identical, so the 2 branches should give the same code. This is the case with gcc and the zeta function:
mov eax, DWORD PTR [rdi+4]
ret
On the other hand, the 2 branches using [[(un)likely]]
retain the cmp
instruction with clang:
cmp dword ptr [rdi], 0
mov eax, dword ptr [rdi + 4]
ret
Testes with clang-15, clang-16 and clang-trunk.