Issue |
135109
|
Summary |
[libc++] `atomic_ref<float>::fetch_add` has CAS loop rather than `atomicrmw`
|
Labels |
libc++
|
Assignees |
|
Reporter |
kc9jud
|
When trying to use `std::atomic_ref<float>` I discovered that I was not getting the IR and ASM I was expecting. It turns out that `std::atomic_ref<float>` and `std::atomic<float>` have very different implementations of `fetch_add` and `fetch_sub`.
Compare https://github.com/llvm/llvm-project/blob/56b792322aaaa82883d56a322a94448de519f789/libcxx/include/__atomic/atomic.h#L382-L389 versus https://github.com/llvm/llvm-project/blob/56b792322aaaa82883d56a322a94448de519f789/libcxx/include/__atomic/atomic_ref.h#L324-L331
`atomic_ref<float>` implements `fetch_add` using a compare-and-swap loop, whereas `atomic<float>` can emit an `atomicrmw fadd`. For architectures with atomic floating-point instructions, this propagates down into dramatically different assembler: https://godbolt.org/z/7KxG5eoe3
Is there a reason why `atomic_ref` has to handle this differently than `atomic`? The `atomic_ref<int>` implementation of `fetch_add` delegates to the builtin `__atomic_fetch_add`: https://github.com/llvm/llvm-project/blob/56b792322aaaa82883d56a322a94448de519f789/libcxx/include/__atomic/atomic_ref.h#L278-L280 Is there something special about floating-point which means the floating-point overloads of `__atomic_fetch_add` are unusable?
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs