https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65247
Bug ID: 65247 Summary: [missed optimisation] Reading a callee-saved register writes to the stack Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: adam at consulting dot net.nz 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.