https://godbolt.org/z/jEM7nrKhs With the following code ```cpp 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: ```asm mov eax, DWORD PTR [rdi+4] ret ``` On the other hand, the 2 branches using `[[(un)likely]]` retain the `cmp` instruction with clang: ```asm cmp dword ptr [rdi], 0 mov eax, dword ptr [rdi + 4] ret ``` Testes with clang-15, clang-16 and clang-trunk.