title: Why does icc fail to handle compile-time branch hints in a reasonable way?
body: <p>A developer can use the <code>__builtin_expect</code> <a href="https://stackoverflow.com/q/109710/149138">builtin</a> to help the compiler <a href="https://stackoverflow.com/q/15468042/149138">understand</a> in which direction a branch is <em>likely</em> to go. </p>
  
  <p>In the future, we may get a <a href="https://stackoverflow.com/q/41665775/149138">standard attribute</a> for this purpose, but as of today at least all of <code>clang</code>, <code>icc</code> and <code>gcc</code> support  the non-standard <code>__builtin_expect</code> instead.</p>
  
  <p>However, <code>icc</code> seems to generate oddly terrible code when you use it<sup>1</sup>. That is, code that is uses the builtin is strictly worse than the code without it, regardless of which direction the prediction is made.</p>
  
  <p>Take for example the following toy function:</p>
  
  <pre><code>int foo(int a, int b)
  {
    do {
       a *= 77;
    } while (b-- &gt; 0);  
    return a * 77;
  }
  </code></pre>
  
  <p>Out of the three compilers, <code>icc</code> is the only one that compiles this to the <a href="https://godbolt.org/g/PA1ATn" rel="nofollow noreferrer">optimal scalar loop</a> of 3 instructions:</p>
  
  <pre><code>foo(int, int):
  ..B1.2:                         # Preds ..B1.2 ..B1.1
          imul      edi, edi, 77                                  #4.6
          dec       esi                                           #5.12
          jns       ..B1.2        # Prob 82%                      #5.18
          imul      eax, edi, 77                                  #6.14
          ret          
  </code></pre>
  
  <p>Both <a href="https://godbolt.org/g/4mHqK7" rel="nofollow noreferrer">gcc</a> and <a href="https://godbolt.org/g/SC1kPW" rel="nofollow noreferrer">Clang</a> manage the miss the easy solution and use 5 instructions.</p>
  
  <p>On the other hand, when you use <code>likely</code> or <code>unlikely</code> macros on the loop condition, <code>icc</code> goes totally braindead:</p>
  
  <pre><code>#define likely(x)   __builtin_expect((x), 1)
  #define unlikely(x) __builtin_expect((x), 0)
  
  int foo(int a, int b)
  {
  
     do {
       a *= 77;
    } while (likely(b-- &gt; 0));  
  
     return a * 77;
  }
  </code></pre>
  
  <p>This loop is functionally equivalent to the previous loop (since <code>__builtin_expect</code> just returns its first argument), yet <a href="https://godbolt.org/g/Kr4AMn" rel="nofollow noreferrer">icc produces some awful code</a>:</p>
  
  <pre><code>foo(int, int):
          mov       eax, 1                                        #9.12
  ..B1.2:                         # Preds ..B1.2 ..B1.1
          xor       edx, edx                                      #9.12
          test      esi, esi                                      #9.12
          cmovg     edx, eax                                      #9.12
          dec       esi                                           #9.12
          imul      edi, edi, 77                                  #8.6
          test      edx, edx                                      #9.12
          jne       ..B1.2        # Prob 95%                      #9.12
          imul      eax, edi, 77                                  #11.15
          ret                                                     #11.15
  </code></pre>
  
  <p>The function has doubled in size to 10 instructions, and (worse yet!) the critical loop has more than doubled to 7 instructions with a long critical dependency chain involving a <code>cmov</code> and other weird stuff.</p>
  
  <p>The same is true if you use the <a href="https://godbolt.org/g/ijqVDN" rel="nofollow noreferrer"><code>unlikely</code> hint</a> and also across all icc versions (13, 14, 17) that godbolt supports. So the code generation is strictly worse, regardless of the hint, and regardless of the actual runtime behavior.</p>
  
  <p>Neither <code>gcc</code> nor <code>clang</code> suffer any degradation when hints are used.</p>
  
  <p>What's up with that?</p>
  
  <hr>
  
  <p><sup>1</sup> At least in the first and subsequent examples I tried.</p>