[libcxx-commits] [libcxx] [libc++][In progress] Floating Point Atomic (PR #67799)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Fri Oct 20 10:35:50 PDT 2023


================
@@ -0,0 +1,260 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+// ADDITIONAL_COMPILE_FLAGS(has-latomic): -latomic
+
+// bool compare_exchange_weak(T& expected, T desired,
+//                            memory_order success, memory_order failure) volatile noexcept;
+// bool compare_exchange_weak(T& expected, T desired,
+//                            memory_order success, memory_order failure) noexcept;
+// bool compare_exchange_weak(T& expected, T desired,
+//                            memory_order order = memory_order::seq_cst) volatile noexcept;
+// bool compare_exchange_weak(T& expected, T desired,
+//                            memory_order order = memory_order::seq_cst) noexcept;
+
+#include <atomic>
+#include <cassert>
+#include <concepts>
+#include <type_traits>
+
+#include "test_helper.h"
+#include "test_macros.h"
+
+template <class T, class... Args>
+concept HasVolatileCompareExchangeWeak =
+    requires(volatile std::atomic<T>& a, T t, Args... args) { a.compare_exchange_weak(t, t, args...); };
+
+template <class T, template <class> class MaybeVolatile, class... Args>
+concept HasNoexceptCompareExchangeWeak = requires(MaybeVolatile<std::atomic<T>>& a, T t, Args... args) {
+  { a.compare_exchange_weak(t, t, args...) } noexcept;
+};
+
+template <class T, template <class> class MaybeVolatile = std::type_identity_t, class... MemoryOrder>
+void testBasic(MemoryOrder... memory_order) {
+  // Uncomment the test after P1831R1 is implemented
+  // static_assert(HasVolatileCompareExchangeWeak<T, MemoryOrder...> == std::atomic<T>::is_always_lock_free);
+  static_assert(HasNoexceptCompareExchangeWeak<T, MaybeVolatile, MemoryOrder...>);
+
+  // compare pass
+  {
+    MaybeVolatile<std::atomic<T>> a(T(1.2));
+    T expected(1.2);
+    const T desired(2.3);
+    std::same_as<bool> decltype(auto) r = a.compare_exchange_weak(expected, desired, memory_order...);
+
+    // could be false spuriously
+    if (r) {
+      assert(a.load() == desired);
+    }
+    // if r is true, expected should be unmodified (1.2)
+    // if r is false, the original value of a (1.2) is written to expected
+    assert(expected == T(1.2));
+  }
+
+  // compare fail
+  {
+    MaybeVolatile<std::atomic<T>> a(T(1.2));
+    T expected(1.5);
+    const T desired(2.3);
+    std::same_as<bool> decltype(auto) r = a.compare_exchange_weak(expected, desired, memory_order...);
+
+    assert(!r);
+    assert(a.load() == T(1.2));
+
+    // bug
+    // https://github.com/llvm/llvm-project/issues/47978
+    if constexpr (!std::same_as<T, long double>) {
+      assert(expected == T(1.2));
+    }
+  }
+}
+
+// https://github.com/llvm/llvm-project/issues/47978
+template <class A, class T>
+void workaroundClangBug(A& atomic, T& expected) {
----------------
ldionne wrote:

I would remove this since it doesn't work on all platforms, and instead I would `UNSUPPORTED: clang` with a comment pointing to the bug report, and explaining that we can't `XFAIL` because the test times out.

https://github.com/llvm/llvm-project/pull/67799


More information about the libcxx-commits mailing list