|
11 | 11 |
|
12 | 12 | #include <__atomic/atomic_sync.h>
|
13 | 13 | #include <__atomic/check_memory_order.h>
|
| 14 | +#include <__atomic/floating_point_helper.h> |
14 | 15 | #include <__atomic/is_always_lock_free.h>
|
15 | 16 | #include <__atomic/memory_order.h>
|
16 | 17 | #include <__atomic/support.h>
|
@@ -332,41 +333,17 @@ template <class _Tp>
|
332 | 333 | requires is_floating_point_v<_Tp>
|
333 | 334 | struct atomic<_Tp> : __atomic_base<_Tp> {
|
334 | 335 | private:
|
335 |
| - _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_fp80_long_double() { |
336 |
| - // Only x87-fp80 long double has 64-bit mantissa |
337 |
| - return __LDBL_MANT_DIG__ == 64 && std::is_same_v<_Tp, long double>; |
338 |
| - } |
339 |
| - |
340 |
| - _LIBCPP_HIDE_FROM_ABI static constexpr bool __has_rmw_builtin() { |
341 |
| -# ifndef _LIBCPP_COMPILER_CLANG_BASED |
342 |
| - return false; |
343 |
| -# else |
344 |
| - // The builtin __cxx_atomic_fetch_add errors during compilation for |
345 |
| - // long double on platforms with fp80 format. |
346 |
| - // For more details, see |
347 |
| - // lib/Sema/SemaChecking.cpp function IsAllowedValueType |
348 |
| - // LLVM Parser does not allow atomicrmw with x86_fp80 type. |
349 |
| - // if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) && |
350 |
| - // &Context.getTargetInfo().getLongDoubleFormat() == |
351 |
| - // &llvm::APFloat::x87DoubleExtended()) |
352 |
| - // For more info |
353 |
| - // https://llvm.org/PR68602 |
354 |
| - // https://reviews.llvm.org/D53965 |
355 |
| - return !__is_fp80_long_double(); |
356 |
| -# endif |
357 |
| - } |
358 |
| - |
359 | 336 | template <class _This, class _Operation, class _BuiltinOp>
|
360 | 337 | _LIBCPP_HIDE_FROM_ABI static _Tp
|
361 | 338 | __rmw_op(_This&& __self, _Tp __operand, memory_order __m, _Operation __operation, _BuiltinOp __builtin_op) {
|
362 |
| - if constexpr (__has_rmw_builtin()) { |
| 339 | + if constexpr (std::__has_rmw_builtin<_Tp>()) { |
363 | 340 | return __builtin_op(std::addressof(std::forward<_This>(__self).__a_), __operand, __m);
|
364 | 341 | } else {
|
365 | 342 | _Tp __old = __self.load(memory_order_relaxed);
|
366 | 343 | _Tp __new = __operation(__old, __operand);
|
367 | 344 | while (!__self.compare_exchange_weak(__old, __new, __m, memory_order_relaxed)) {
|
368 | 345 | # ifdef _LIBCPP_COMPILER_CLANG_BASED
|
369 |
| - if constexpr (__is_fp80_long_double()) { |
| 346 | + if constexpr (std::__is_fp80_long_double<_Tp>()) { |
370 | 347 | // https://llvm.org/PR47978
|
371 | 348 | // clang bug: __old is not updated on failure for atomic<long double>::compare_exchange_weak
|
372 | 349 | // Note __old = __self.load(memory_order_relaxed) will not work
|
|
0 commit comments