[libcxx-commits] [libcxx] [libc++][test] Use loop with compare_exchange_weak calls (PR #185953)

Jake Egan via libcxx-commits libcxx-commits at lists.llvm.org
Wed Mar 11 12:00:52 PDT 2026


https://github.com/jakeegan created https://github.com/llvm/llvm-project/pull/185953

On AIX, this test sometimes fails with error `Assertion failed: y == true`. The test assumes `compare_exchange_weak` should succeed on a single call, however according to the standard:

> A weak compare-and-exchange operation may fail spuriously. That is, even when the contents of memory referred to by expected and ptr are equal, it may return false and store back to expected the same memory contents that were originally there.
This spurious failure enables implementation of compare-and-exchange on a broader class of machines, e.g., load-locked store-conditional machines. A consequence of spurious failure is that nearly all uses of weak compare-and-exchange will be in a loop.

[atomics.ref.ops]/27

>From 964f616aafd780eae197dc86955514eb7a6f9c62 Mon Sep 17 00:00:00 2001
From: Jake Egan <jake.egan at ibm.com>
Date: Wed, 11 Mar 2026 14:43:48 -0400
Subject: [PATCH] [libc++] Use loop with compare_echange_weak test

---
 .../atomics.ref/compare_exchange_weak.pass.cpp  | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/libcxx/test/std/atomics/atomics.ref/compare_exchange_weak.pass.cpp b/libcxx/test/std/atomics/atomics.ref/compare_exchange_weak.pass.cpp
index 58cf2e0fe338b..58c15f6265d4b 100644
--- a/libcxx/test/std/atomics/atomics.ref/compare_exchange_weak.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.ref/compare_exchange_weak.pass.cpp
@@ -33,11 +33,10 @@ struct TestCompareExchangeWeak {
       std::atomic_ref<T> const a(x);
 
       T t(T(1));
-      std::same_as<bool> decltype(auto) y = a.compare_exchange_weak(t, T(2));
-      assert(y == true);
+      while(!a.compare_exchange_weak(t, T(2)));
       assert(a == T(2));
       assert(t == T(1));
-      y = a.compare_exchange_weak(t, T(3));
+      std::same_as<bool> decltype(auto) y = a.compare_exchange_weak(t, T(3));
       assert(y == false);
       assert(a == T(2));
       assert(t == T(2));
@@ -49,11 +48,10 @@ struct TestCompareExchangeWeak {
       std::atomic_ref<T> const a(x);
 
       T t(T(1));
-      std::same_as<bool> decltype(auto) y = a.compare_exchange_weak(t, T(2), std::memory_order_seq_cst);
-      assert(y == true);
+      while(!a.compare_exchange_weak(t, T(2), std::memory_order_seq_cst));
       assert(a == T(2));
       assert(t == T(1));
-      y = a.compare_exchange_weak(t, T(3), std::memory_order_seq_cst);
+      std::same_as<bool> decltype(auto) y = a.compare_exchange_weak(t, T(3), std::memory_order_seq_cst);
       assert(y == false);
       assert(a == T(2));
       assert(t == T(2));
@@ -65,12 +63,11 @@ struct TestCompareExchangeWeak {
       std::atomic_ref<T> const a(x);
 
       T t(T(1));
-      std::same_as<bool> decltype(auto) y =
-          a.compare_exchange_weak(t, T(2), std::memory_order_release, std::memory_order_relaxed);
-      assert(y == true);
+      while(!a.compare_exchange_weak(t, T(2), std::memory_order_release, std::memory_order_relaxed));
       assert(a == T(2));
       assert(t == T(1));
-      y = a.compare_exchange_weak(t, T(3), std::memory_order_release, std::memory_order_relaxed);
+      std::same_as<bool> decltype(auto) y = 
+          a.compare_exchange_weak(t, T(3), std::memory_order_release, std::memory_order_relaxed);
       assert(y == false);
       assert(a == T(2));
       assert(t == T(2));



More information about the libcxx-commits mailing list