[llvm-branch-commits] [libcxx] release/22.x: [libc++][test] Use loop with compare_exchange_weak calls (#185953) (PR #194642)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Apr 28 07:25:50 PDT 2026


https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/194642

Backport 3fea2f61652e10c7f3abc17f0542e8bc0dd0ea25

Requested by: @alexrp

>From 7f005004bf9e1d7e4dcfeb240e84e268034c9318 Mon Sep 17 00:00:00 2001
From: Jake Egan <Jake.egan at ibm.com>
Date: Sat, 14 Mar 2026 22:34:48 -0400
Subject: [PATCH] [libc++][test] Use loop with compare_exchange_weak calls
 (#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

(cherry picked from commit 3fea2f61652e10c7f3abc17f0542e8bc0dd0ea25)
---
 .../compare_exchange_weak.pass.cpp            | 20 +++++++++----------
 1 file changed, 10 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 99c1385a2fe0b..0d9ccd93533a0 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
@@ -32,11 +32,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));
-      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));
@@ -48,11 +48,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_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));
@@ -64,12 +64,12 @@ 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 llvm-branch-commits mailing list