https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102566
--- Comment #15 from Thiago Macieira <thiago at kde dot org> --- Works now for the failing case. Additionally: bool tbit(std::atomic<long> &i) { return i.fetch_and(~CONSTANT, std::memory_order_relaxed) & (CONSTANT); } Will properly produce LOCK BTR (CONSTANT=2): lock btrq $1, (%rdi) setc %al ret CONSTANT=(1L<<62): lock btrq $62, (%rdi) setc %al ret But not for CONSTANT=1 or CONSTANT=(1L<<63): movq (%rdi), %rax .L2: movq %rax, %rcx movq %rax, %rdx andq $-2, %rcx lock cmpxchgq %rcx, (%rdi) jne .L2 movl %edx, %eax andl $1, %eax ret Same applies to 1<<31 for atomic<int>.