https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112844
--- Comment #4 from Petr Skocik <pskocik at gmail dot com> ---
(In reply to Jakub Jelinek from comment #1)
> With -Os you ask the code to be small. So, while internally the hint is
> still present in edge probabilities, -Os is considered more important and
> certain code changes based on the probabilities aren't done if they are
> known or expected to result in larger code.
I think this approach is abit problematic because
(a) it fails to deliver the promised smaller code
e.g., the following
void fn(void);
void maybefn(int X){ if(__builtin_expect(X,0)) fn(); }
under gcc -Os codegens
maybefn:
testl %edi, %edi
je .L1
jmp fn
.L1:
ret
which is 1-jmp-larger than what you'd get if the compiler followed the hint
(clang's codegen):
maybefn:
test edi, edi
jne fn@PLT
ret
(b) when following the branch hints does lead to codesize increases, it's
usually stuff like
before:;
if (unlikely(cnd)){ branch; }
after:;
codegenning:
before: ...; if(cnd) goto branch_begin; after: ...
branch: ... goto after;
rather than the 1-goto-shorter:
before: ...; if(!cnd) goto after; branch: ...; after: ...
IOW, it just tends to be 1 extra jump (which often is near enough to be
2-byte-encoded), which IMO, is not worth worrying about. I would personally
prefer that the compiler always follow the hint when the hint is expressed
since the hint can make (a small but definite) performance difference and the
size cost is negligible (or even negative as shown above).