<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Greedy spilling of registers before unlikely branch pessimizes likely code path"
   href="https://bugs.llvm.org/show_bug.cgi?id=41398">41398</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Greedy spilling of registers before unlikely branch pessimizes likely code path
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>Register Allocator
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>vgatherps@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org, quentin.colombet@gmail.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Hi, when building the following code with both clang -Os and -O3 on x86_64:

int callme();

int test_function(int a, int b) {
    if (__builtin_expect(b < 10, 0)) {
        a += callme();
    }
    return a * b;
}

generates

test_function(int, int):
        pushq   %rbp
        pushq   %rbx
        pushq   %rax
        movl    %esi, %ebx
        movl    %edi, %ebp
        cmpl    $9, %esi
        jle     .LBB0_1
.LBB0_2:
        imull   %ebx, %ebp
        movl    %ebp, %eax
        addq    $8, %rsp
        popq    %rbx
        popq    %rbp
        retq
.LBB0_1:
        callq   callme()
        addl    %eax, %ebp
        jmp     .LBB0_2

instead of something like

test_function(int, int):

        cmpl    $9, %esi
        jle     .LBB0_1
.LBB0_2:
        imull   %edi, %esi
        movl    %esi, %eax
        retq
.LBB0_1:
        pushq   %edi
        pushq   %esi
        callq   callme()
        popq    %esi
        popq    %edi
        addl    %eax, %edi
        jmp     .LBB0_2

While it might be a valid decision to always save to stack if there's a likely
or normal call, this is undesirable behavior when the calling function is
marked as unlikely since branch probably won't get taken and the function
probably won't get called.

As a side note, when compiling with -Os, it would make more sense to just save
esi and edi instead of saving into non-scratch registers and pushing those old
values anyways, both from a code size and stack size perspective. This isn't
really the main point of the bug though.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>