Skip to content

[[likely]] and [[unlikely]] ignored with jump to tail call #126363

@eisenwave

Description

@eisenwave

https://godbolt.org/z/TY4ovb9ss

void t(), f();

void decide(bool ok) {
    if (ok) [[likely]] {
        t();
    } else {
        f();
    }
}

The use of [[likely]] or [[unlikely]] here has no effect whatsoever, and regardless which attribute is applied, Clang always optimizes to:

decide(bool):
        test    edi, edi
        je      f()@PLT
        jmp     t()@PLT

When [[likely]] is applied to calling t(), this is bad output because it would be better to let je t() succeed instead of letting je f() fail and then doing jmp t(). MSVC handles attributes correctly in this case.

Initially, I thought this is some edge case and path ordering issue, but maybe it isn't. When using [[likely]], LowerExpectIntrinsicPass does:

-%loadedv.expval = call i1 @llvm.expect.i1(i1 %loadedv, i1 true)
-br i1 %loadedv.expval, label %if.then, label %if.else
+br i1 %loadedv, label %if.then, label %if.else

When replacing [[likely]] with [[unlikely]]:

-%loadedv.expval = call i1 @llvm.expect.i1(i1 %loadedv, i1 false)
-br i1 %loadedv.expval, label %if.then, label %if.else
+br i1 %loadedv, label %if.then, label %if.else

Maybe I'm not getting something about the optimization pipeline, but from that point on, the IR is identical, so it looks like [[likely]] and [[unlikely]] are always ignored completely. This also happens when the contents of if/else are something different.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions