<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </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 --- - [missed optimisation] Reading a callee-saved register writes to the stack"
   href="http://llvm.org/bugs/show_bug.cgi?id=22735">22735</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>[missed optimisation] Reading a callee-saved register writes to the stack
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

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

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

        <tr>
          <th>OS</th>
          <td>Linux
          </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>-New Bugs
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>adam@consulting.net.nz
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>There is no way to inform the compiler one is reading a callee-saved register
without the compiler also writing the register to the stack:

read_callee_saved_register.c:
#include <stdint.h>

uint64_t read_rbx(void) {
  register uint64_t rbx asm ("rbx");
  uint64_t value;
  asm ("mov %[rbx], %[value]" : [value] "=r" (value) : [rbx] "r" (rbx));
  return value;
}

int main(void) {
  return 0;
}

The code above explicitly tells the complier that local register variable rbx
is only being read. Here is the output of gcc and clang respectively:

$ gcc-snapshot.sh -O3 read_callee_saved_register.c && objdump -d -m i386:x86-64
a.out|less
00000000004004c0 <read_rbx>:
  4004c0:       48 89 d8                mov    %rbx,%rax
  4004c3:       53                      push   %rbx
  4004c4:       5b                      pop    %rbx
  4004c5:       c3                      retq   
  4004c6:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  4004cd:       00 00 00

$ clang-3.7 -O3 read_callee_saved_register.c && objdump -d -m i386:x86-64
a.out|less
00000000004004e0 <read_rbx>:
  4004e0:       53                      push   %rbx
  4004e1:       48 89 d8                mov    %rbx,%rax
  4004e4:       5b                      pop    %rbx
  4004e5:       c3                      retq   
  4004e6:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
  4004ed:       00 00 00

Neither gcc nor clang should be pushing and popping rbx. 

Note: gcc already trusts that rbx is merely being read since the assembly is
inserted before rbx is pushed and popped off the stack.</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>