https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109362
--- Comment #1 from Barry Revzin <barry.revzin at gmail dot com> --- Sorry, in this reduced example, it doesn't actually consume an extra register - only rdi is used. In this slightly less reduced example: #include <atomic> struct S { std::atomic<long> size; std::atomic<char*> read_ptr; auto peek() const -> const char* { auto const s = size.load(std::memory_order_acquire); return read_ptr.load(std::memory_order_acquire); } }; auto with_atomic(S const& v) { while (true) { if (v.peek()) { return true; } } } the codegen is: with_atomic(WithAtomic const&): lea rdx, [rdi+8] .L2: mov rax, QWORD PTR [rdi] mov rax, QWORD PTR [rdx] test rax, rax je .L2 mov eax, 1 ret which now does consume rdx unnecessarily.