I have not specified the gcc version; it seems like it applies to any version. I have noticed that if I write code: #include <stdatomic.h> int func(_Atomic(int) *a) { return (atomic_fetch_sub(a, 1) - 1 == 0); } gcc generates optimized code (gcc -O2): func: .LFB0: .cfi_startproc xorl %eax, %eax lock subl $1, (%rdi) sete %al ret But when I change the condition to <= 0, it does not work. Correct me if I am wrong, but, I think, it should still be able to use sub: #include <stdatomic.h> int func(_Atomic(int) *a) { return (atomic_fetch_sub(a, 1) - 1 <= 0); } func: .LFB0: .cfi_startproc movl $-1, %eax lock xaddl %eax, (%rdi) cmpl $1, %eax setle %al movzbl %al, %eax ret Seems like the same problem exists for atomic_fetch_add as well.
btw, the same problem for #include <stdatomic.h> int func(_Atomic(long) *a) { return (atomic_fetch_sub(a, 1) <= 0); } In the previous case clang/llvm was just like gcc, i.e., unable to optimize; in this case clang/llvm was able to produce better code, but gcc still cannot.
Confirmed.