[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-10-19 Thread via cfe-commits

https://github.com/huixie90 closed 
https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-10-19 Thread via cfe-commits

https://github.com/huixie90 updated 
https://github.com/llvm/llvm-project/pull/78707

>From 0dc5bf91516e2138ed73b602cb17943ef6bcc878 Mon Sep 17 00:00:00 2001
From: Hui 
Date: Fri, 19 Jan 2024 12:33:43 +
Subject: [PATCH 01/10] [libc++] fix _Atomic c11 compare exchange does not
 update expected results

---
 clang/lib/CodeGen/CGAtomic.cpp | 61 +-
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 4a3446abcc78f..01d02c2dbed45 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
   Address Dest, Address Ptr,
   Address Val1, Address Val2,
+  Address ExpectedResult,
   uint64_t Size,
   llvm::AtomicOrdering SuccessOrder,
   llvm::AtomicOrdering FailureOrder,
@@ -411,9 +412,17 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  auto *I = CGF.Builder.CreateStore(Old, Val1);
-  CGF.addInstToCurrentSourceAtom(I, Old);
 
+  llvm::Type *ExpectedType = ExpectedResult.getElementType();
+  uint64_t OriginalSizeInBits = 
CGF.CGM.getDataLayout().getTypeSizeInBits(ExpectedType);
+  if (OriginalSizeInBits / 8 == Size) {
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  } else {
+// How to just store N bytes to ExpectedResult ?
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  }
   // Finally, branch to the exit point.
   CGF.Builder.CreateBr(ContinueBB);
 
@@ -428,6 +437,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
 bool IsWeak, Address Dest, Address Ptr,
 Address Val1, Address Val2,
+Address ExpectedResult,
 llvm::Value *FailureOrderVal,
 uint64_t Size,
 llvm::AtomicOrdering SuccessOrder,
@@ -458,7 +468,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 // success argument". This condition has been lifted and the only
 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
 // language version checks.
-emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 
SuccessOrder,
+emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
   FailureOrder, Scope);
 return;
   }
@@ -483,17 +493,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 
   // Emit all the different atomics
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, 
Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(AcquireBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::Acquire, Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(SeqCstBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::SequentiallyConsistent, Scope);
   CGF.Builder.CreateBr(ContBB);
 
@@ -526,6 +536,7 @@ static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy 
&Builder,
 
 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
  Address Ptr, Address Val1, Address Val2,
+ Address ExpectedResult,
  llvm::Value *IsWeak, llvm::Value *FailureOrder,
  uint64_t Size, llvm::AtomicOrdering Order,
  llvm::SyncScope::ID Scope) {
@@ -542,13 +553,13 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr 
*E, Address Dest,
   case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
   case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
-Failur

[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-10-19 Thread via cfe-commits

https://github.com/huixie90 updated 
https://github.com/llvm/llvm-project/pull/78707

>From 0dc5bf91516e2138ed73b602cb17943ef6bcc878 Mon Sep 17 00:00:00 2001
From: Hui 
Date: Fri, 19 Jan 2024 12:33:43 +
Subject: [PATCH 1/9] [libc++] fix _Atomic c11 compare exchange does not update
 expected results

---
 clang/lib/CodeGen/CGAtomic.cpp | 61 +-
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 4a3446abcc78f..01d02c2dbed45 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
   Address Dest, Address Ptr,
   Address Val1, Address Val2,
+  Address ExpectedResult,
   uint64_t Size,
   llvm::AtomicOrdering SuccessOrder,
   llvm::AtomicOrdering FailureOrder,
@@ -411,9 +412,17 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  auto *I = CGF.Builder.CreateStore(Old, Val1);
-  CGF.addInstToCurrentSourceAtom(I, Old);
 
+  llvm::Type *ExpectedType = ExpectedResult.getElementType();
+  uint64_t OriginalSizeInBits = 
CGF.CGM.getDataLayout().getTypeSizeInBits(ExpectedType);
+  if (OriginalSizeInBits / 8 == Size) {
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  } else {
+// How to just store N bytes to ExpectedResult ?
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  }
   // Finally, branch to the exit point.
   CGF.Builder.CreateBr(ContinueBB);
 
@@ -428,6 +437,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
 bool IsWeak, Address Dest, Address Ptr,
 Address Val1, Address Val2,
+Address ExpectedResult,
 llvm::Value *FailureOrderVal,
 uint64_t Size,
 llvm::AtomicOrdering SuccessOrder,
@@ -458,7 +468,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 // success argument". This condition has been lifted and the only
 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
 // language version checks.
-emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 
SuccessOrder,
+emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
   FailureOrder, Scope);
 return;
   }
@@ -483,17 +493,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 
   // Emit all the different atomics
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, 
Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(AcquireBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::Acquire, Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(SeqCstBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::SequentiallyConsistent, Scope);
   CGF.Builder.CreateBr(ContBB);
 
@@ -526,6 +536,7 @@ static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy 
&Builder,
 
 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
  Address Ptr, Address Val1, Address Val2,
+ Address ExpectedResult,
  llvm::Value *IsWeak, llvm::Value *FailureOrder,
  uint64_t Size, llvm::AtomicOrdering Order,
  llvm::SyncScope::ID Scope) {
@@ -542,13 +553,13 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr 
*E, Address Dest,
   case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
   case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
-FailureO

[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-10-19 Thread via cfe-commits


@@ -0,0 +1,70 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// https://github.com/llvm/llvm-project/issues/30023
+// compare exchange does not work with types of which the size is not a power 
of 2
+
+// XFAIL: clang-20, clang-21, apple-clang-15, apple-clang-16, apple-clang-17

huixie90 wrote:

Discussed with @ldionne offline. We agreed to `UNSUPPORTED: clang-22` as 
suggested with a TODO. once libc++'s CI's docker image is updated with clang 
with this patch, we can re-enable the test

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-10-19 Thread via cfe-commits

https://github.com/huixie90 updated 
https://github.com/llvm/llvm-project/pull/78707

>From 0dc5bf91516e2138ed73b602cb17943ef6bcc878 Mon Sep 17 00:00:00 2001
From: Hui 
Date: Fri, 19 Jan 2024 12:33:43 +
Subject: [PATCH 1/8] [libc++] fix _Atomic c11 compare exchange does not update
 expected results

---
 clang/lib/CodeGen/CGAtomic.cpp | 61 +-
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 4a3446abcc78f..01d02c2dbed45 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
   Address Dest, Address Ptr,
   Address Val1, Address Val2,
+  Address ExpectedResult,
   uint64_t Size,
   llvm::AtomicOrdering SuccessOrder,
   llvm::AtomicOrdering FailureOrder,
@@ -411,9 +412,17 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  auto *I = CGF.Builder.CreateStore(Old, Val1);
-  CGF.addInstToCurrentSourceAtom(I, Old);
 
+  llvm::Type *ExpectedType = ExpectedResult.getElementType();
+  uint64_t OriginalSizeInBits = 
CGF.CGM.getDataLayout().getTypeSizeInBits(ExpectedType);
+  if (OriginalSizeInBits / 8 == Size) {
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  } else {
+// How to just store N bytes to ExpectedResult ?
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  }
   // Finally, branch to the exit point.
   CGF.Builder.CreateBr(ContinueBB);
 
@@ -428,6 +437,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
 bool IsWeak, Address Dest, Address Ptr,
 Address Val1, Address Val2,
+Address ExpectedResult,
 llvm::Value *FailureOrderVal,
 uint64_t Size,
 llvm::AtomicOrdering SuccessOrder,
@@ -458,7 +468,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 // success argument". This condition has been lifted and the only
 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
 // language version checks.
-emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 
SuccessOrder,
+emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
   FailureOrder, Scope);
 return;
   }
@@ -483,17 +493,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 
   // Emit all the different atomics
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, 
Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(AcquireBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::Acquire, Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(SeqCstBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::SequentiallyConsistent, Scope);
   CGF.Builder.CreateBr(ContBB);
 
@@ -526,6 +536,7 @@ static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy 
&Builder,
 
 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
  Address Ptr, Address Val1, Address Val2,
+ Address ExpectedResult,
  llvm::Value *IsWeak, llvm::Value *FailureOrder,
  uint64_t Size, llvm::AtomicOrdering Order,
  llvm::SyncScope::ID Scope) {
@@ -542,13 +553,13 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr 
*E, Address Dest,
   case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
   case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
-FailureO

[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-10-18 Thread via cfe-commits

https://github.com/huixie90 updated 
https://github.com/llvm/llvm-project/pull/78707

>From b55baba51a605218da71a3f1a893d9e2b98e9182 Mon Sep 17 00:00:00 2001
From: Hui 
Date: Fri, 19 Jan 2024 12:33:43 +
Subject: [PATCH 1/5] [libc++] fix _Atomic c11 compare exchange does not update
 expected results

---
 clang/lib/CodeGen/CGAtomic.cpp | 61 +-
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 4a3446abcc78f..01d02c2dbed45 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
   Address Dest, Address Ptr,
   Address Val1, Address Val2,
+  Address ExpectedResult,
   uint64_t Size,
   llvm::AtomicOrdering SuccessOrder,
   llvm::AtomicOrdering FailureOrder,
@@ -411,9 +412,17 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  auto *I = CGF.Builder.CreateStore(Old, Val1);
-  CGF.addInstToCurrentSourceAtom(I, Old);
 
+  llvm::Type *ExpectedType = ExpectedResult.getElementType();
+  uint64_t OriginalSizeInBits = 
CGF.CGM.getDataLayout().getTypeSizeInBits(ExpectedType);
+  if (OriginalSizeInBits / 8 == Size) {
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  } else {
+// How to just store N bytes to ExpectedResult ?
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  }
   // Finally, branch to the exit point.
   CGF.Builder.CreateBr(ContinueBB);
 
@@ -428,6 +437,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
 bool IsWeak, Address Dest, Address Ptr,
 Address Val1, Address Val2,
+Address ExpectedResult,
 llvm::Value *FailureOrderVal,
 uint64_t Size,
 llvm::AtomicOrdering SuccessOrder,
@@ -458,7 +468,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 // success argument". This condition has been lifted and the only
 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
 // language version checks.
-emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 
SuccessOrder,
+emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
   FailureOrder, Scope);
 return;
   }
@@ -483,17 +493,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 
   // Emit all the different atomics
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, 
Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(AcquireBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::Acquire, Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(SeqCstBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::SequentiallyConsistent, Scope);
   CGF.Builder.CreateBr(ContBB);
 
@@ -526,6 +536,7 @@ static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy 
&Builder,
 
 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
  Address Ptr, Address Val1, Address Val2,
+ Address ExpectedResult,
  llvm::Value *IsWeak, llvm::Value *FailureOrder,
  uint64_t Size, llvm::AtomicOrdering Order,
  llvm::SyncScope::ID Scope) {
@@ -542,13 +553,13 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr 
*E, Address Dest,
   case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
   case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
-FailureO

[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-10-18 Thread via cfe-commits

huixie90 wrote:

> I think the current state addresses my concerns, yes. I'd like to make one 
> final pass over it, though; please git-clang-format and rebase the patch.

Thanks I rebased and clang-formatted the changed lines.  The CI fails on the 
new test I added in libc++, because the libc++ is not using the just-built 
clang for testing for majority of the targets and they fail as expected. i will 
check with @ldionne  how to skip the previous versions of clangs for that test

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-10-18 Thread via cfe-commits

https://github.com/huixie90 updated 
https://github.com/llvm/llvm-project/pull/78707

>From 0dc5bf91516e2138ed73b602cb17943ef6bcc878 Mon Sep 17 00:00:00 2001
From: Hui 
Date: Fri, 19 Jan 2024 12:33:43 +
Subject: [PATCH 1/6] [libc++] fix _Atomic c11 compare exchange does not update
 expected results

---
 clang/lib/CodeGen/CGAtomic.cpp | 61 +-
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 4a3446abcc78f..01d02c2dbed45 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
   Address Dest, Address Ptr,
   Address Val1, Address Val2,
+  Address ExpectedResult,
   uint64_t Size,
   llvm::AtomicOrdering SuccessOrder,
   llvm::AtomicOrdering FailureOrder,
@@ -411,9 +412,17 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  auto *I = CGF.Builder.CreateStore(Old, Val1);
-  CGF.addInstToCurrentSourceAtom(I, Old);
 
+  llvm::Type *ExpectedType = ExpectedResult.getElementType();
+  uint64_t OriginalSizeInBits = 
CGF.CGM.getDataLayout().getTypeSizeInBits(ExpectedType);
+  if (OriginalSizeInBits / 8 == Size) {
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  } else {
+// How to just store N bytes to ExpectedResult ?
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  }
   // Finally, branch to the exit point.
   CGF.Builder.CreateBr(ContinueBB);
 
@@ -428,6 +437,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
 bool IsWeak, Address Dest, Address Ptr,
 Address Val1, Address Val2,
+Address ExpectedResult,
 llvm::Value *FailureOrderVal,
 uint64_t Size,
 llvm::AtomicOrdering SuccessOrder,
@@ -458,7 +468,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 // success argument". This condition has been lifted and the only
 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
 // language version checks.
-emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 
SuccessOrder,
+emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
   FailureOrder, Scope);
 return;
   }
@@ -483,17 +493,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 
   // Emit all the different atomics
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, 
Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(AcquireBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::Acquire, Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(SeqCstBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::SequentiallyConsistent, Scope);
   CGF.Builder.CreateBr(ContBB);
 
@@ -526,6 +536,7 @@ static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy 
&Builder,
 
 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
  Address Ptr, Address Val1, Address Val2,
+ Address ExpectedResult,
  llvm::Value *IsWeak, llvm::Value *FailureOrder,
  uint64_t Size, llvm::AtomicOrdering Order,
  llvm::SyncScope::ID Scope) {
@@ -542,13 +553,13 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr 
*E, Address Dest,
   case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
   case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
-FailureO

[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-10-18 Thread via cfe-commits

https://github.com/huixie90 updated 
https://github.com/llvm/llvm-project/pull/78707

>From 0dc5bf91516e2138ed73b602cb17943ef6bcc878 Mon Sep 17 00:00:00 2001
From: Hui 
Date: Fri, 19 Jan 2024 12:33:43 +
Subject: [PATCH 1/5] [libc++] fix _Atomic c11 compare exchange does not update
 expected results

---
 clang/lib/CodeGen/CGAtomic.cpp | 61 +-
 1 file changed, 37 insertions(+), 24 deletions(-)

diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 4a3446abcc78f..01d02c2dbed45 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
   Address Dest, Address Ptr,
   Address Val1, Address Val2,
+  Address ExpectedResult,
   uint64_t Size,
   llvm::AtomicOrdering SuccessOrder,
   llvm::AtomicOrdering FailureOrder,
@@ -411,9 +412,17 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  auto *I = CGF.Builder.CreateStore(Old, Val1);
-  CGF.addInstToCurrentSourceAtom(I, Old);
 
+  llvm::Type *ExpectedType = ExpectedResult.getElementType();
+  uint64_t OriginalSizeInBits = 
CGF.CGM.getDataLayout().getTypeSizeInBits(ExpectedType);
+  if (OriginalSizeInBits / 8 == Size) {
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  } else {
+// How to just store N bytes to ExpectedResult ?
+auto *I = CGF.Builder.CreateStore(Old, ExpectedResult);
+CGF.addInstToCurrentSourceAtom(I, Old);
+  }
   // Finally, branch to the exit point.
   CGF.Builder.CreateBr(ContinueBB);
 
@@ -428,6 +437,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
 bool IsWeak, Address Dest, Address Ptr,
 Address Val1, Address Val2,
+Address ExpectedResult,
 llvm::Value *FailureOrderVal,
 uint64_t Size,
 llvm::AtomicOrdering SuccessOrder,
@@ -458,7 +468,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 // success argument". This condition has been lifted and the only
 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
 // language version checks.
-emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 
SuccessOrder,
+emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
   FailureOrder, Scope);
 return;
   }
@@ -483,17 +493,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 
   // Emit all the different atomics
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, 
Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(AcquireBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::Acquire, Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(SeqCstBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::SequentiallyConsistent, Scope);
   CGF.Builder.CreateBr(ContBB);
 
@@ -526,6 +536,7 @@ static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy 
&Builder,
 
 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
  Address Ptr, Address Val1, Address Val2,
+ Address ExpectedResult,
  llvm::Value *IsWeak, llvm::Value *FailureOrder,
  uint64_t Size, llvm::AtomicOrdering Order,
  llvm::SyncScope::ID Scope) {
@@ -542,13 +553,13 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr 
*E, Address Dest,
   case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
   case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
-FailureO

[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-10-17 Thread Louis Dionne via cfe-commits


@@ -0,0 +1,70 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// https://github.com/llvm/llvm-project/issues/30023
+// compare exchange does not work with types of which the size is not a power 
of 2
+
+// XFAIL: clang-20, clang-21, apple-clang-15, apple-clang-16, apple-clang-17

ldionne wrote:

I can't find a solution for the clang version issue right now, I will have to 
think about it a bit more.

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-10-13 Thread Louis Dionne via cfe-commits




ldionne wrote:

Let's give a real name to this test file.

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-09-30 Thread Eli Friedman via cfe-commits

efriedma-quic wrote:

I think the current state addresses my concerns, yes.  I'd like to make one 
final pass over it, though; please git-clang-format and rebase the patch.

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-09-27 Thread via cfe-commits

huixie90 wrote:

ping @efriedma-quic  does the current status address your concerns?

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-07-04 Thread Louis Dionne via cfe-commits

ldionne wrote:

CC @philnik777 in case you want to take a look as well

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-07-04 Thread Louis Dionne via cfe-commits


@@ -0,0 +1,65 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// https://github.com/llvm/llvm-project/issues/30023
+// compare exchange does not work with types of which the size is not a power 
of 2
+
+#include 
+#include 
+#include 
+
+template 
+struct S {
+  char data[Size];
+
+  explicit S(char v = 0) noexcept { memset(&data[0], v, sizeof(data)); }
+
+  // only used in the test to check the results. Not used in atomic operations.
+  friend bool operator==(const S& lhs, const S& rhs) noexcept {
+return memcmp(&lhs.data[0], &rhs.data[0], sizeof(lhs.data)) == 0;
+  }
+  friend bool operator!=(const S& lhs, const S& rhs) noexcept { return !(lhs 
== rhs); }
+};
+
+template 
+struct Expected {
+  S s;
+  bool b = true; // used to validate that s's operation won't overwrite the 
memory next to it
+};
+
+template 
+void test() {
+  using T = S;
+  std::atomic a(T(0));
+  Expected expected{T(17)};
+
+  assert(a.load() != expected.s);
+  assert(expected.b);
+
+  auto r1 = a.compare_exchange_strong(expected.s, T(18), 
std::memory_order_relaxed);
+
+  assert(!r1);
+  assert(expected.s == T(0)); // expected.s is modified by 
compare_exchange_strong
+  assert(expected.b);
+  assert(a.load() == T(0));
+
+  auto r2 = a.compare_exchange_strong(expected.s, T(18), 
std::memory_order_relaxed);
+  assert(r2);
+  assert(a.load() == T(18));
+  assert(expected.s == T(0));
+  assert(expected.b);
+}
+
+int main() {

ldionne wrote:

```suggestion
int main(int, char**) {
```

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-07-04 Thread Louis Dionne via cfe-commits


@@ -411,7 +412,33 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();

ldionne wrote:

Nitpick: this looks mis-formatted.

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-07-04 Thread Louis Dionne via cfe-commits


@@ -0,0 +1,65 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+
+// https://github.com/llvm/llvm-project/issues/30023
+// compare exchange does not work with types of which the size is not a power 
of 2
+
+#include 
+#include 
+#include 
+
+template 
+struct S {
+  char data[Size];
+
+  explicit S(char v = 0) noexcept { memset(&data[0], v, sizeof(data)); }
+
+  // only used in the test to check the results. Not used in atomic operations.
+  friend bool operator==(const S& lhs, const S& rhs) noexcept {
+return memcmp(&lhs.data[0], &rhs.data[0], sizeof(lhs.data)) == 0;
+  }
+  friend bool operator!=(const S& lhs, const S& rhs) noexcept { return !(lhs 
== rhs); }
+};
+
+template 
+struct Expected {
+  S s;
+  bool b = true; // used to validate that s's operation won't overwrite the 
memory next to it
+};
+
+template 
+void test() {
+  using T = S;
+  std::atomic a(T(0));
+  Expected expected{T(17)};
+
+  assert(a.load() != expected.s);
+  assert(expected.b);
+
+  auto r1 = a.compare_exchange_strong(expected.s, T(18), 
std::memory_order_relaxed);
+
+  assert(!r1);
+  assert(expected.s == T(0)); // expected.s is modified by 
compare_exchange_strong
+  assert(expected.b);
+  assert(a.load() == T(0));
+
+  auto r2 = a.compare_exchange_strong(expected.s, T(18), 
std::memory_order_relaxed);
+  assert(r2);
+  assert(a.load() == T(18));
+  assert(expected.s == T(0));
+  assert(expected.b);
+}
+
+int main() {
+  test<1>();
+  test<2>();
+  test<3>();
+  test<4>();
+  test<5>();
+  test<6>();
+}

ldionne wrote:

```suggestion
  test<6>();
  return 0;
}
```

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-07-04 Thread Louis Dionne via cfe-commits


@@ -0,0 +1,65 @@
+//===--===//
+//
+// 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
+//
+//===--===//
+

ldionne wrote:

This is going to require something like

```
// XFAIL: clang-20, apple-clang-15, apple-clang-16
```

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-07-04 Thread Louis Dionne via cfe-commits

https://github.com/ldionne edited 
https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-07-04 Thread Louis Dionne via cfe-commits

https://github.com/ldionne commented:

This looks quite reasonable to me, and it seems we're fixing a pretty bad bug. 
However, someone else with more Clang/Codegen experience needs to look at this. 
Thanks for working on this!

CC @efriedma-quic 

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-21 Thread via cfe-commits


@@ -411,7 +412,48 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();
+const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
+uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(ExpectedType);
+
+if (ExpectedSizeInBytes == Size) {
+  // Sizes match: store directly
+  CGF.Builder.CreateStore(Old, ExpectedResult);
+
+} else {
+  // store only the first ExpectedSizeInBytes bytes of Old
+  llvm::Type *OldType = Old->getType();
+
+  llvm::Align SrcAlignLLVM = DL.getABITypeAlign(OldType);
+  llvm::Align DstAlignLLVM = DL.getABITypeAlign(ExpectedType);
+
+  clang::CharUnits SrcAlign = 
clang::CharUnits::fromQuantity(SrcAlignLLVM.value());
+  clang::CharUnits DstAlign = 
clang::CharUnits::fromQuantity(DstAlignLLVM.value());
+
+  // Allocate temporary storage for Old value
+  llvm::AllocaInst *Alloca = CGF.CreateTempAlloca(OldType, "old.tmp");
+
+  // Wrap into clang::CodeGen::Address with proper type and alignment
+  Address OldStorage(Alloca, OldType, SrcAlign);
+
+  // Store Old into this temporary
+  CGF.Builder.CreateStore(Old, OldStorage);
+
+  // Bitcast pointers to i8*
+  llvm::Type *I8PtrTy = llvm::PointerType::getUnqual(CGF.getLLVMContext());
+
+  llvm::Value *SrcPtr = CGF.Builder.CreateBitCast(OldStorage.getBasePointer(), 
I8PtrTy);
+  llvm::Value *DstPtr = 
CGF.Builder.CreateBitCast(ExpectedResult.getBasePointer(), I8PtrTy);

huixie90 wrote:

cool thanks. I had another go. @efriedma-quic  could you please see if it is 
something look more reasonable to you? thanks

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-21 Thread via cfe-commits

https://github.com/huixie90 updated 
https://github.com/llvm/llvm-project/pull/78707

>From 904f24aa69b5df2e52a9f19c3e96fa94b47aec82 Mon Sep 17 00:00:00 2001
From: Hui 
Date: Fri, 19 Jan 2024 12:33:43 +
Subject: [PATCH 1/3] [libc++] fix _Atomic c11 compare exchange does not update
 expected results

---
 clang/lib/CodeGen/CGAtomic.cpp | 59 +-
 1 file changed, 36 insertions(+), 23 deletions(-)

diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 51f0799a792fd..033a12ef93848 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
   Address Dest, Address Ptr,
   Address Val1, Address Val2,
+  Address ExpectedResult,
   uint64_t Size,
   llvm::AtomicOrdering SuccessOrder,
   llvm::AtomicOrdering FailureOrder,
@@ -411,7 +412,15 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+
+  llvm::Type *ExpectedType = ExpectedResult.getElementType();
+  uint64_t OriginalSizeInBits = 
CGF.CGM.getDataLayout().getTypeSizeInBits(ExpectedType);
+  if (OriginalSizeInBits / 8 == Size) {
+CGF.Builder.CreateStore(Old, ExpectedResult);
+  } else {
+// How to just store N bytes to ExpectedResult ?
+CGF.Builder.CreateStore(Old, ExpectedResult);
+  }
   // Finally, branch to the exit point.
   CGF.Builder.CreateBr(ContinueBB);
 
@@ -426,6 +435,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
 bool IsWeak, Address Dest, Address Ptr,
 Address Val1, Address Val2,
+Address ExpectedResult,
 llvm::Value *FailureOrderVal,
 uint64_t Size,
 llvm::AtomicOrdering SuccessOrder,
@@ -456,7 +466,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 // success argument". This condition has been lifted and the only
 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
 // language version checks.
-emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 
SuccessOrder,
+emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
   FailureOrder, Scope);
 return;
   }
@@ -481,17 +491,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 
   // Emit all the different atomics
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, 
Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(AcquireBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::Acquire, Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(SeqCstBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::SequentiallyConsistent, Scope);
   CGF.Builder.CreateBr(ContBB);
 
@@ -524,6 +534,7 @@ static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy 
&Builder,
 
 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
  Address Ptr, Address Val1, Address Val2,
+ Address ExpectedResult,
  llvm::Value *IsWeak, llvm::Value *FailureOrder,
  uint64_t Size, llvm::AtomicOrdering Order,
  llvm::SyncScope::ID Scope) {
@@ -540,13 +551,13 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr 
*E, Address Dest,
   case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
   case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
-FailureOrder, Size, Order, Scope);
+ExpectedResult, FailureOrder, Size, Order, 
Scope);
 return;
   case AtomicExpr::AO__c11_atomic_com

[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-21 Thread via cfe-commits


@@ -411,7 +412,48 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();
+const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
+uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(ExpectedType);
+
+if (ExpectedSizeInBytes == Size) {
+  // Sizes match: store directly
+  CGF.Builder.CreateStore(Old, ExpectedResult);
+
+} else {
+  // store only the first ExpectedSizeInBytes bytes of Old
+  llvm::Type *OldType = Old->getType();
+
+  llvm::Align SrcAlignLLVM = DL.getABITypeAlign(OldType);
+  llvm::Align DstAlignLLVM = DL.getABITypeAlign(ExpectedType);
+
+  clang::CharUnits SrcAlign = 
clang::CharUnits::fromQuantity(SrcAlignLLVM.value());
+  clang::CharUnits DstAlign = 
clang::CharUnits::fromQuantity(DstAlignLLVM.value());

huixie90 wrote:

Since `Old` is the result of the compare exchange. I assume it has the same 
alignment of the atomic address itself. so I used the `Ptr.getAlignment()` 
here. would that be fine?

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-21 Thread via cfe-commits


@@ -411,7 +412,48 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();
+const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
+uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(ExpectedType);
+
+if (ExpectedSizeInBytes == Size) {
+  // Sizes match: store directly
+  CGF.Builder.CreateStore(Old, ExpectedResult);
+
+} else {
+  // store only the first ExpectedSizeInBytes bytes of Old
+  llvm::Type *OldType = Old->getType();
+
+  llvm::Align SrcAlignLLVM = DL.getABITypeAlign(OldType);
+  llvm::Align DstAlignLLVM = DL.getABITypeAlign(ExpectedType);
+
+  clang::CharUnits SrcAlign = 
clang::CharUnits::fromQuantity(SrcAlignLLVM.value());
+  clang::CharUnits DstAlign = 
clang::CharUnits::fromQuantity(DstAlignLLVM.value());

huixie90 wrote:

thanks. I replaced the DstAlignLLVM thing with `ExpectedResult.getAlignment()`. 
However, for `Old`, I don't have an `Address`, could you please advice the 
right way to get the alignment from an `llvm::Value`?

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-16 Thread Eli Friedman via cfe-commits


@@ -411,7 +412,48 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();
+const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
+uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(ExpectedType);
+
+if (ExpectedSizeInBytes == Size) {
+  // Sizes match: store directly
+  CGF.Builder.CreateStore(Old, ExpectedResult);
+
+} else {
+  // store only the first ExpectedSizeInBytes bytes of Old
+  llvm::Type *OldType = Old->getType();
+
+  llvm::Align SrcAlignLLVM = DL.getABITypeAlign(OldType);
+  llvm::Align DstAlignLLVM = DL.getABITypeAlign(ExpectedType);
+
+  clang::CharUnits SrcAlign = 
clang::CharUnits::fromQuantity(SrcAlignLLVM.value());
+  clang::CharUnits DstAlign = 
clang::CharUnits::fromQuantity(DstAlignLLVM.value());
+
+  // Allocate temporary storage for Old value
+  llvm::AllocaInst *Alloca = CGF.CreateTempAlloca(OldType, "old.tmp");
+
+  // Wrap into clang::CodeGen::Address with proper type and alignment
+  Address OldStorage(Alloca, OldType, SrcAlign);
+
+  // Store Old into this temporary
+  CGF.Builder.CreateStore(Old, OldStorage);
+
+  // Bitcast pointers to i8*
+  llvm::Type *I8PtrTy = llvm::PointerType::getUnqual(CGF.getLLVMContext());
+
+  llvm::Value *SrcPtr = CGF.Builder.CreateBitCast(OldStorage.getBasePointer(), 
I8PtrTy);
+  llvm::Value *DstPtr = 
CGF.Builder.CreateBitCast(ExpectedResult.getBasePointer(), I8PtrTy);

efriedma-quic wrote:

The code here is doing the right thing, roughly: doing an alloca+store+memcpy 
is fine.  (SROA will usually end up optimizing it, but the exact sequence of 
instructions you need isn't consistent, so it's fine to rely on that.)

My suggestions are basically code cleanup: don't do redundant operations, 
compute alignment consistently, use appropriate helper methods.

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-14 Thread via cfe-commits


@@ -411,7 +412,48 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();
+const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
+uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(ExpectedType);
+
+if (ExpectedSizeInBytes == Size) {
+  // Sizes match: store directly
+  CGF.Builder.CreateStore(Old, ExpectedResult);
+
+} else {
+  // store only the first ExpectedSizeInBytes bytes of Old
+  llvm::Type *OldType = Old->getType();
+
+  llvm::Align SrcAlignLLVM = DL.getABITypeAlign(OldType);
+  llvm::Align DstAlignLLVM = DL.getABITypeAlign(ExpectedType);
+
+  clang::CharUnits SrcAlign = 
clang::CharUnits::fromQuantity(SrcAlignLLVM.value());
+  clang::CharUnits DstAlign = 
clang::CharUnits::fromQuantity(DstAlignLLVM.value());
+
+  // Allocate temporary storage for Old value
+  llvm::AllocaInst *Alloca = CGF.CreateTempAlloca(OldType, "old.tmp");
+
+  // Wrap into clang::CodeGen::Address with proper type and alignment
+  Address OldStorage(Alloca, OldType, SrcAlign);
+
+  // Store Old into this temporary
+  CGF.Builder.CreateStore(Old, OldStorage);
+
+  // Bitcast pointers to i8*
+  llvm::Type *I8PtrTy = llvm::PointerType::getUnqual(CGF.getLLVMContext());
+
+  llvm::Value *SrcPtr = CGF.Builder.CreateBitCast(OldStorage.getBasePointer(), 
I8PtrTy);
+  llvm::Value *DstPtr = 
CGF.Builder.CreateBitCast(ExpectedResult.getBasePointer(), I8PtrTy);

huixie90 wrote:

Hi thanks for the review. Could you please point me the right way of doing 
this? The entire code in the `else` branch is just doing one thing. Copy the 
first N bytes from the `Old` to `ExpectedResults`.

The rational is as follows. when we do compare exchange , if the input type is 
not of size power of two, say, it is 36 bytes. we first allocate 48 bytes 
temporary, do the compare exchange with the temporary. Then we need to also 
update the "expected" when the exchange does Not happen. but we cannot copy the 
full 48 bytes back to "expected". because user only passed in an address with 
36 bytes.

What is the right way of copying first N bytes from Old to ExpectedResults?

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-14 Thread via cfe-commits

https://github.com/huixie90 edited 
https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-09 Thread Eli Friedman via cfe-commits


@@ -411,7 +412,48 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();
+const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
+uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(ExpectedType);
+
+if (ExpectedSizeInBytes == Size) {
+  // Sizes match: store directly
+  CGF.Builder.CreateStore(Old, ExpectedResult);
+
+} else {
+  // store only the first ExpectedSizeInBytes bytes of Old
+  llvm::Type *OldType = Old->getType();
+
+  llvm::Align SrcAlignLLVM = DL.getABITypeAlign(OldType);
+  llvm::Align DstAlignLLVM = DL.getABITypeAlign(ExpectedType);
+
+  clang::CharUnits SrcAlign = 
clang::CharUnits::fromQuantity(SrcAlignLLVM.value());
+  clang::CharUnits DstAlign = 
clang::CharUnits::fromQuantity(DstAlignLLVM.value());

efriedma-quic wrote:

This is not the correct way to query alignment in general.

An Address should already have alignment encoded in it.

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-09 Thread Eli Friedman via cfe-commits


@@ -411,7 +412,48 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();
+const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
+uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(ExpectedType);
+
+if (ExpectedSizeInBytes == Size) {
+  // Sizes match: store directly
+  CGF.Builder.CreateStore(Old, ExpectedResult);
+
+} else {
+  // store only the first ExpectedSizeInBytes bytes of Old
+  llvm::Type *OldType = Old->getType();
+
+  llvm::Align SrcAlignLLVM = DL.getABITypeAlign(OldType);
+  llvm::Align DstAlignLLVM = DL.getABITypeAlign(ExpectedType);
+
+  clang::CharUnits SrcAlign = 
clang::CharUnits::fromQuantity(SrcAlignLLVM.value());
+  clang::CharUnits DstAlign = 
clang::CharUnits::fromQuantity(DstAlignLLVM.value());
+
+  // Allocate temporary storage for Old value
+  llvm::AllocaInst *Alloca = CGF.CreateTempAlloca(OldType, "old.tmp");
+
+  // Wrap into clang::CodeGen::Address with proper type and alignment
+  Address OldStorage(Alloca, OldType, SrcAlign);
+
+  // Store Old into this temporary
+  CGF.Builder.CreateStore(Old, OldStorage);
+
+  // Bitcast pointers to i8*
+  llvm::Type *I8PtrTy = llvm::PointerType::getUnqual(CGF.getLLVMContext());
+
+  llvm::Value *SrcPtr = CGF.Builder.CreateBitCast(OldStorage.getBasePointer(), 
I8PtrTy);
+  llvm::Value *DstPtr = 
CGF.Builder.CreateBitCast(ExpectedResult.getBasePointer(), I8PtrTy);

efriedma-quic wrote:

Bitcasts don't do anything with opaque pointers.

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-09 Thread Eli Friedman via cfe-commits


@@ -411,7 +412,48 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();
+const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
+uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(ExpectedType);
+
+if (ExpectedSizeInBytes == Size) {
+  // Sizes match: store directly
+  CGF.Builder.CreateStore(Old, ExpectedResult);
+
+} else {
+  // store only the first ExpectedSizeInBytes bytes of Old
+  llvm::Type *OldType = Old->getType();
+
+  llvm::Align SrcAlignLLVM = DL.getABITypeAlign(OldType);
+  llvm::Align DstAlignLLVM = DL.getABITypeAlign(ExpectedType);
+
+  clang::CharUnits SrcAlign = 
clang::CharUnits::fromQuantity(SrcAlignLLVM.value());
+  clang::CharUnits DstAlign = 
clang::CharUnits::fromQuantity(DstAlignLLVM.value());
+
+  // Allocate temporary storage for Old value
+  llvm::AllocaInst *Alloca = CGF.CreateTempAlloca(OldType, "old.tmp");

efriedma-quic wrote:

I think there's a variant of CreateTempAlloca that returns an Address?

https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-07 Thread via cfe-commits

https://github.com/huixie90 edited 
https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-07 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang-codegen

Author: Hui (huixie90)


Changes

fixes #30023

---

Patch is 24.34 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/78707.diff


3 Files Affected:

- (modified) clang/lib/CodeGen/CGAtomic.cpp (+69-23) 
- (added) clang/test/CodeGenCXX/builtin-atomic-compare_exchange.cpp (+126) 
- (added) libcxx/test/std/atomics/atomics.types.generic/30023.pass.cpp (+65) 


``diff
diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 51f0799a792fd..9eee834a520e0 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
   Address Dest, Address Ptr,
   Address Val1, Address Val2,
+  Address ExpectedResult,
   uint64_t Size,
   llvm::AtomicOrdering SuccessOrder,
   llvm::AtomicOrdering FailureOrder,
@@ -411,7 +412,48 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();
+const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
+uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(ExpectedType);
+
+if (ExpectedSizeInBytes == Size) {
+  // Sizes match: store directly
+  CGF.Builder.CreateStore(Old, ExpectedResult);
+
+} else {
+  // store only the first ExpectedSizeInBytes bytes of Old
+  llvm::Type *OldType = Old->getType();
+
+  llvm::Align SrcAlignLLVM = DL.getABITypeAlign(OldType);
+  llvm::Align DstAlignLLVM = DL.getABITypeAlign(ExpectedType);
+
+  clang::CharUnits SrcAlign = 
clang::CharUnits::fromQuantity(SrcAlignLLVM.value());
+  clang::CharUnits DstAlign = 
clang::CharUnits::fromQuantity(DstAlignLLVM.value());
+
+  // Allocate temporary storage for Old value
+  llvm::AllocaInst *Alloca = CGF.CreateTempAlloca(OldType, "old.tmp");
+
+  // Wrap into clang::CodeGen::Address with proper type and alignment
+  Address OldStorage(Alloca, OldType, SrcAlign);
+
+  // Store Old into this temporary
+  CGF.Builder.CreateStore(Old, OldStorage);
+
+  // Bitcast pointers to i8*
+  llvm::Type *I8PtrTy = llvm::PointerType::getUnqual(CGF.getLLVMContext());
+
+  llvm::Value *SrcPtr = CGF.Builder.CreateBitCast(OldStorage.getBasePointer(), 
I8PtrTy);
+  llvm::Value *DstPtr = 
CGF.Builder.CreateBitCast(ExpectedResult.getBasePointer(), I8PtrTy);
+
+  // Perform memcpy for first ExpectedSizeInBytes bytes
+  CGF.Builder.CreateMemCpy(
+DstPtr, DstAlignLLVM,
+SrcPtr, SrcAlignLLVM,
+llvm::ConstantInt::get(CGF.IntPtrTy, ExpectedSizeInBytes),
+/*isVolatile=*/false);
+}
+
+  
   // Finally, branch to the exit point.
   CGF.Builder.CreateBr(ContinueBB);
 
@@ -426,6 +468,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
 bool IsWeak, Address Dest, Address Ptr,
 Address Val1, Address Val2,
+Address ExpectedResult,
 llvm::Value *FailureOrderVal,
 uint64_t Size,
 llvm::AtomicOrdering SuccessOrder,
@@ -456,7 +499,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 // success argument". This condition has been lifted and the only
 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
 // language version checks.
-emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 
SuccessOrder,
+emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
   FailureOrder, Scope);
 return;
   }
@@ -481,17 +524,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 
   // Emit all the different atomics
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, 
Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(AcquireBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::Acquire, Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(SeqCstBB);
-  emitAto

[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-07 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-libcxx

Author: Hui (huixie90)


Changes

fixes #30023

---

Patch is 24.34 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/78707.diff


3 Files Affected:

- (modified) clang/lib/CodeGen/CGAtomic.cpp (+69-23) 
- (added) clang/test/CodeGenCXX/builtin-atomic-compare_exchange.cpp (+126) 
- (added) libcxx/test/std/atomics/atomics.types.generic/30023.pass.cpp (+65) 


``diff
diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 51f0799a792fd..9eee834a520e0 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
   Address Dest, Address Ptr,
   Address Val1, Address Val2,
+  Address ExpectedResult,
   uint64_t Size,
   llvm::AtomicOrdering SuccessOrder,
   llvm::AtomicOrdering FailureOrder,
@@ -411,7 +412,48 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();
+const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
+uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(ExpectedType);
+
+if (ExpectedSizeInBytes == Size) {
+  // Sizes match: store directly
+  CGF.Builder.CreateStore(Old, ExpectedResult);
+
+} else {
+  // store only the first ExpectedSizeInBytes bytes of Old
+  llvm::Type *OldType = Old->getType();
+
+  llvm::Align SrcAlignLLVM = DL.getABITypeAlign(OldType);
+  llvm::Align DstAlignLLVM = DL.getABITypeAlign(ExpectedType);
+
+  clang::CharUnits SrcAlign = 
clang::CharUnits::fromQuantity(SrcAlignLLVM.value());
+  clang::CharUnits DstAlign = 
clang::CharUnits::fromQuantity(DstAlignLLVM.value());
+
+  // Allocate temporary storage for Old value
+  llvm::AllocaInst *Alloca = CGF.CreateTempAlloca(OldType, "old.tmp");
+
+  // Wrap into clang::CodeGen::Address with proper type and alignment
+  Address OldStorage(Alloca, OldType, SrcAlign);
+
+  // Store Old into this temporary
+  CGF.Builder.CreateStore(Old, OldStorage);
+
+  // Bitcast pointers to i8*
+  llvm::Type *I8PtrTy = llvm::PointerType::getUnqual(CGF.getLLVMContext());
+
+  llvm::Value *SrcPtr = CGF.Builder.CreateBitCast(OldStorage.getBasePointer(), 
I8PtrTy);
+  llvm::Value *DstPtr = 
CGF.Builder.CreateBitCast(ExpectedResult.getBasePointer(), I8PtrTy);
+
+  // Perform memcpy for first ExpectedSizeInBytes bytes
+  CGF.Builder.CreateMemCpy(
+DstPtr, DstAlignLLVM,
+SrcPtr, SrcAlignLLVM,
+llvm::ConstantInt::get(CGF.IntPtrTy, ExpectedSizeInBytes),
+/*isVolatile=*/false);
+}
+
+  
   // Finally, branch to the exit point.
   CGF.Builder.CreateBr(ContinueBB);
 
@@ -426,6 +468,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
 bool IsWeak, Address Dest, Address Ptr,
 Address Val1, Address Val2,
+Address ExpectedResult,
 llvm::Value *FailureOrderVal,
 uint64_t Size,
 llvm::AtomicOrdering SuccessOrder,
@@ -456,7 +499,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 // success argument". This condition has been lifted and the only
 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
 // language version checks.
-emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 
SuccessOrder,
+emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
   FailureOrder, Scope);
 return;
   }
@@ -481,17 +524,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 
   // Emit all the different atomics
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, 
Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(AcquireBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::Acquire, Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(SeqCstBB);
-  emitAtomicCmpX

[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-07 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Hui (huixie90)


Changes

fixes #30023

---

Patch is 24.34 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/78707.diff


3 Files Affected:

- (modified) clang/lib/CodeGen/CGAtomic.cpp (+69-23) 
- (added) clang/test/CodeGenCXX/builtin-atomic-compare_exchange.cpp (+126) 
- (added) libcxx/test/std/atomics/atomics.types.generic/30023.pass.cpp (+65) 


``diff
diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 51f0799a792fd..9eee834a520e0 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
   Address Dest, Address Ptr,
   Address Val1, Address Val2,
+  Address ExpectedResult,
   uint64_t Size,
   llvm::AtomicOrdering SuccessOrder,
   llvm::AtomicOrdering FailureOrder,
@@ -411,7 +412,48 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+llvm::Type *ExpectedType = ExpectedResult.getElementType();
+const llvm::DataLayout &DL = CGF.CGM.getDataLayout();
+uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(ExpectedType);
+
+if (ExpectedSizeInBytes == Size) {
+  // Sizes match: store directly
+  CGF.Builder.CreateStore(Old, ExpectedResult);
+
+} else {
+  // store only the first ExpectedSizeInBytes bytes of Old
+  llvm::Type *OldType = Old->getType();
+
+  llvm::Align SrcAlignLLVM = DL.getABITypeAlign(OldType);
+  llvm::Align DstAlignLLVM = DL.getABITypeAlign(ExpectedType);
+
+  clang::CharUnits SrcAlign = 
clang::CharUnits::fromQuantity(SrcAlignLLVM.value());
+  clang::CharUnits DstAlign = 
clang::CharUnits::fromQuantity(DstAlignLLVM.value());
+
+  // Allocate temporary storage for Old value
+  llvm::AllocaInst *Alloca = CGF.CreateTempAlloca(OldType, "old.tmp");
+
+  // Wrap into clang::CodeGen::Address with proper type and alignment
+  Address OldStorage(Alloca, OldType, SrcAlign);
+
+  // Store Old into this temporary
+  CGF.Builder.CreateStore(Old, OldStorage);
+
+  // Bitcast pointers to i8*
+  llvm::Type *I8PtrTy = llvm::PointerType::getUnqual(CGF.getLLVMContext());
+
+  llvm::Value *SrcPtr = CGF.Builder.CreateBitCast(OldStorage.getBasePointer(), 
I8PtrTy);
+  llvm::Value *DstPtr = 
CGF.Builder.CreateBitCast(ExpectedResult.getBasePointer(), I8PtrTy);
+
+  // Perform memcpy for first ExpectedSizeInBytes bytes
+  CGF.Builder.CreateMemCpy(
+DstPtr, DstAlignLLVM,
+SrcPtr, SrcAlignLLVM,
+llvm::ConstantInt::get(CGF.IntPtrTy, ExpectedSizeInBytes),
+/*isVolatile=*/false);
+}
+
+  
   // Finally, branch to the exit point.
   CGF.Builder.CreateBr(ContinueBB);
 
@@ -426,6 +468,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
 bool IsWeak, Address Dest, Address Ptr,
 Address Val1, Address Val2,
+Address ExpectedResult,
 llvm::Value *FailureOrderVal,
 uint64_t Size,
 llvm::AtomicOrdering SuccessOrder,
@@ -456,7 +499,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 // success argument". This condition has been lifted and the only
 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
 // language version checks.
-emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 
SuccessOrder,
+emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
   FailureOrder, Scope);
 return;
   }
@@ -481,17 +524,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 
   // Emit all the different atomics
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, 
Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(AcquireBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::Acquire, Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(SeqCstBB);
-  emitAtomicCmpXc

[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-07 Thread via cfe-commits

https://github.com/huixie90 updated 
https://github.com/llvm/llvm-project/pull/78707

>From 904f24aa69b5df2e52a9f19c3e96fa94b47aec82 Mon Sep 17 00:00:00 2001
From: Hui 
Date: Fri, 19 Jan 2024 12:33:43 +
Subject: [PATCH 1/2] [libc++] fix _Atomic c11 compare exchange does not update
 expected results

---
 clang/lib/CodeGen/CGAtomic.cpp | 59 +-
 1 file changed, 36 insertions(+), 23 deletions(-)

diff --git a/clang/lib/CodeGen/CGAtomic.cpp b/clang/lib/CodeGen/CGAtomic.cpp
index 51f0799a792fd..033a12ef93848 100644
--- a/clang/lib/CodeGen/CGAtomic.cpp
+++ b/clang/lib/CodeGen/CGAtomic.cpp
@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
   Address Dest, Address Ptr,
   Address Val1, Address Val2,
+  Address ExpectedResult,
   uint64_t Size,
   llvm::AtomicOrdering SuccessOrder,
   llvm::AtomicOrdering FailureOrder,
@@ -411,7 +412,15 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 
   CGF.Builder.SetInsertPoint(StoreExpectedBB);
   // Update the memory at Expected with Old's value.
-  CGF.Builder.CreateStore(Old, Val1);
+
+  llvm::Type *ExpectedType = ExpectedResult.getElementType();
+  uint64_t OriginalSizeInBits = 
CGF.CGM.getDataLayout().getTypeSizeInBits(ExpectedType);
+  if (OriginalSizeInBits / 8 == Size) {
+CGF.Builder.CreateStore(Old, ExpectedResult);
+  } else {
+// How to just store N bytes to ExpectedResult ?
+CGF.Builder.CreateStore(Old, ExpectedResult);
+  }
   // Finally, branch to the exit point.
   CGF.Builder.CreateBr(ContinueBB);
 
@@ -426,6 +435,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, 
AtomicExpr *E, bool IsWeak,
 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
 bool IsWeak, Address Dest, Address Ptr,
 Address Val1, Address Val2,
+Address ExpectedResult,
 llvm::Value *FailureOrderVal,
 uint64_t Size,
 llvm::AtomicOrdering SuccessOrder,
@@ -456,7 +466,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 // success argument". This condition has been lifted and the only
 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
 // language version checks.
-emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 
SuccessOrder,
+emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
   FailureOrder, Scope);
 return;
   }
@@ -481,17 +491,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction 
&CGF, AtomicExpr *E,
 
   // Emit all the different atomics
   CGF.Builder.SetInsertPoint(MonotonicBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, 
Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(AcquireBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::Acquire, Scope);
   CGF.Builder.CreateBr(ContBB);
 
   CGF.Builder.SetInsertPoint(SeqCstBB);
-  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
+  emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, 
Size, SuccessOrder,
 llvm::AtomicOrdering::SequentiallyConsistent, Scope);
   CGF.Builder.CreateBr(ContBB);
 
@@ -524,6 +534,7 @@ static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy 
&Builder,
 
 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
  Address Ptr, Address Val1, Address Val2,
+ Address ExpectedResult,
  llvm::Value *IsWeak, llvm::Value *FailureOrder,
  uint64_t Size, llvm::AtomicOrdering Order,
  llvm::SyncScope::ID Scope) {
@@ -540,13 +551,13 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr 
*E, Address Dest,
   case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
   case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
-FailureOrder, Size, Order, Scope);
+ExpectedResult, FailureOrder, Size, Order, 
Scope);
 return;
   case AtomicExpr::AO__c11_atomic_com

[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-07 Thread via cfe-commits

https://github.com/huixie90 ready_for_review 
https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)

2025-06-07 Thread via cfe-commits

https://github.com/huixie90 edited 
https://github.com/llvm/llvm-project/pull/78707
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits