================ @@ -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 cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits