https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86693
--- Comment #2 from Ruslan Nikolaev <nruslan_devel at yahoo dot com> --- Also may be (partially) related the following cases: 1. #include <stdatomic.h> #include <stdbool.h> void func2(); void func(_Atomic(unsigned long) * obj, void * obj2) { if (atomic_fetch_sub(obj, 1) == 1 && obj2) func2(); } generates 'xadd' when 'sub' suffices: func: .LFB0: .cfi_startproc movq $-1, %rax lock xaddq %rax, (%rdi) testq %rsi, %rsi je .L1 cmpq $1, %rax je .L10 .L1: rep ret .p2align 4,,10 .p2align 3 .L10: xorl %eax, %eax jmp func2@PLT 2. #include <stdatomic.h> int func(_Atomic(unsigned long) * obj, unsigned long a) { return atomic_fetch_add(obj, a) == -a; } generates 'xadd' when 'add' suffices: func: .LFB0: .cfi_startproc movq %rsi, %rax lock xaddq %rax, (%rdi) addq %rsi, %rax sete %al movzbl %al, %eax ret