[clang] [libcxx] [clang] [libc++] fix _Atomic c11 compare exchange does not update expected results (PR #78707)
Eli Friedman via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 9 09:43:34 PDT 2025
================
@@ -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
More information about the cfe-commits
mailing list