https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83610

            Bug ID: 83610
           Summary: __builtin_expect sometimes is ignored
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: bugzi...@poradnik-webmastera.com
  Target Milestone: ---

[code]
void f1();
void f2();

void test(int a, int b, int c, int d, int n, int k)
{
  int val = a & b;
  if (__builtin_expect(!!(n == k), 0))
    val &= c;
  if (__builtin_expect(!!(n == 10 - k), 0))
    val &= d;
  if (val)
    f1();
  else
    f2();
}
[/code]

This code compiled with gcc 4.8.5 generates branches as expected:

[asm]
test(int, int, int, int, int, int):
  and edi, esi
  cmp r8d, r9d
  je .L6
.L2:
  mov eax, 10
  sub eax, r9d
  cmp r8d, eax
  je .L7
.L3:
  test edi, edi
  jne .L8
  jmp f2()
.L8:
  jmp f1()
.L7:
  and edi, ecx
  jmp .L3
.L6:
  and edi, edx
  jmp .L2
[/asm]

When this code is compiled with gcc 4.9.0 or higher, it generates branchless
code like below. In my case it is slower than version with branches. I wanted
to   convince compiler to generate this version of code by using
__builtin_expect, but for some reason it does not work.

[asm]
test(int, int, int, int, int, int):
  and esi, edi
  mov eax, 10
  and edx, esi
  cmp r8d, r9d
  cmove esi, edx
  sub eax, r9d
  and ecx, esi
  cmp r8d, eax
  cmove esi, ecx
  test esi, esi
  jne .L6
  jmp f2()
.L6:
  jmp f1()
[/asm]

Reply via email to