Skip to content

[clang] unnecessary conditions marked with [[likely]] or [[unlikely]] are not removed by the optimizer #69841

Closed
@jonathanpoelen

Description

@jonathanpoelen

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions