================
@@ -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