[libcxx-commits] [PATCH] D103846: [libcxx][atomic] Fix failure mapping in compare_exchange_{strong, weak}.

Jordan Rupprecht via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jun 14 19:14:42 PDT 2021


rupprecht updated this revision to Diff 352033.
rupprecht added a comment.

- Require tsan feature to avoid buildbot jobs that don't support -fsanitize=thread (asan, windows, 32bit, ARMv7/8)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103846/new/

https://reviews.llvm.org/D103846

Files:
  libcxx/include/atomic
  libcxx/test/std/atomics/atomics.general/replace_failure_order_codegen.sh.cpp


Index: libcxx/test/std/atomics/atomics.general/replace_failure_order_codegen.sh.cpp
===================================================================
--- /dev/null
+++ libcxx/test/std/atomics/atomics.general/replace_failure_order_codegen.sh.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: clang
+// UNSUPPORTED: libcpp-has-no-threads
+
+// Adding "-fsanitize=thread" directly causes many platforms to fail (because
+// they don't support tsan), and causes other sanitizer builds to fail (e.g.
+// asan and tsan don't mix). Instead, require the tsan feature.
+// REQUIRES: tsan
+
+// This test verifies behavior specified by [atomics.types.operations.req]/21:
+//
+//     When only one memory_order argument is supplied, the value of success is
+//     order, and the value of failure is order except that a value of
+//     memory_order_acq_rel shall be replaced by the value memory_order_acquire
+//     and a value of memory_order_release shall be replaced by the value
+//     memory_order_relaxed.
+//
+// This test mirrors replace_failure_order.pass.cpp. However, we also want to
+// verify the codegen is correct. This verifies a bug where memory_order_acq_rel
+// was not being replaced with memory_order_acquire in external
+// TSAN-instrumented tests.
+
+// RUN: %{cxx} -c %s %{flags} %{compile_flags} -O2 -stdlib=libc++ -S -emit-llvm -o %t.ll
+
+#include <atomic>
+
+// Note: libc++ tests do not use on FileCheck.
+// RUN: grep -E "call i32 @__tsan_atomic32_compare_exchange_val\(.*, i32 1, i32 4, i32 2\)" %t.ll
+bool strong_memory_order_acq_rel(std::atomic<int>* a, int cmp) {
+  return a->compare_exchange_strong(cmp, 1, std::memory_order_acq_rel);
+}
Index: libcxx/include/atomic
===================================================================
--- libcxx/include/atomic
+++ libcxx/include/atomic
@@ -1017,26 +1017,33 @@
     return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
 }
 
+_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR memory_order __to_failure_order(memory_order __order) {
+  // Avoid switch statement to make this a constexpr.
+  return __order == memory_order_release ? memory_order_relaxed:
+         (__order == memory_order_acq_rel ? memory_order_acquire:
+             __order);
+}
+
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY
 bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
+    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
 }
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY
 bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
+    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
 }
 
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY
 bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
+    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
 }
 template<class _Tp>
 _LIBCPP_INLINE_VISIBILITY
 bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
-    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value,  static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
+    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value,  static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__to_failure_order(__failure)));
 }
 
 template<class _Tp>


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D103846.352033.patch
Type: text/x-patch
Size: 5186 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20210615/423250ad/attachment.bin>


More information about the libcxx-commits mailing list