@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
376376static void emitAtomicCmpXchg (CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
377377 Address Dest, Address Ptr,
378378 Address Val1, Address Val2,
379+ Address ExpectedResult,
379380 uint64_t Size,
380381 llvm::AtomicOrdering SuccessOrder,
381382 llvm::AtomicOrdering FailureOrder,
@@ -411,9 +412,17 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
411412
412413 CGF.Builder .SetInsertPoint (StoreExpectedBB);
413414 // Update the memory at Expected with Old's value.
414- auto *I = CGF.Builder .CreateStore (Old, Val1);
415- CGF.addInstToCurrentSourceAtom (I, Old);
416415
416+ llvm::Type *ExpectedType = ExpectedResult.getElementType ();
417+ uint64_t OriginalSizeInBits = CGF.CGM .getDataLayout ().getTypeSizeInBits (ExpectedType);
418+ if (OriginalSizeInBits / 8 == Size) {
419+ auto *I = CGF.Builder .CreateStore (Old, ExpectedResult);
420+ CGF.addInstToCurrentSourceAtom (I, Old);
421+ } else {
422+ // How to just store N bytes to ExpectedResult ?
423+ auto *I = CGF.Builder .CreateStore (Old, ExpectedResult);
424+ CGF.addInstToCurrentSourceAtom (I, Old);
425+ }
417426 // Finally, branch to the exit point.
418427 CGF.Builder .CreateBr (ContinueBB);
419428
@@ -428,6 +437,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
428437static void emitAtomicCmpXchgFailureSet (CodeGenFunction &CGF, AtomicExpr *E,
429438 bool IsWeak, Address Dest, Address Ptr,
430439 Address Val1, Address Val2,
440+ Address ExpectedResult,
431441 llvm::Value *FailureOrderVal,
432442 uint64_t Size,
433443 llvm::AtomicOrdering SuccessOrder,
@@ -458,7 +468,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
458468 // success argument". This condition has been lifted and the only
459469 // precondition is 31.7.2.18. Effectively treat this as a DR and skip
460470 // language version checks.
461- emitAtomicCmpXchg (CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
471+ emitAtomicCmpXchg (CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, Size, SuccessOrder,
462472 FailureOrder, Scope);
463473 return ;
464474 }
@@ -483,17 +493,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
483493
484494 // Emit all the different atomics
485495 CGF.Builder .SetInsertPoint (MonotonicBB);
486- emitAtomicCmpXchg (CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
496+ emitAtomicCmpXchg (CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
487497 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, Scope);
488498 CGF.Builder .CreateBr (ContBB);
489499
490500 CGF.Builder .SetInsertPoint (AcquireBB);
491- emitAtomicCmpXchg (CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
501+ emitAtomicCmpXchg (CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, Size, SuccessOrder,
492502 llvm::AtomicOrdering::Acquire, Scope);
493503 CGF.Builder .CreateBr (ContBB);
494504
495505 CGF.Builder .SetInsertPoint (SeqCstBB);
496- emitAtomicCmpXchg (CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder,
506+ emitAtomicCmpXchg (CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult, Size, SuccessOrder,
497507 llvm::AtomicOrdering::SequentiallyConsistent, Scope);
498508 CGF.Builder .CreateBr (ContBB);
499509
@@ -526,6 +536,7 @@ static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy &Builder,
526536
527537static void EmitAtomicOp (CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
528538 Address Ptr, Address Val1, Address Val2,
539+ Address ExpectedResult,
529540 llvm::Value *IsWeak, llvm::Value *FailureOrder,
530541 uint64_t Size, llvm::AtomicOrdering Order,
531542 llvm::SyncScope::ID Scope) {
@@ -542,21 +553,21 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
542553 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
543554 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
544555 emitAtomicCmpXchgFailureSet (CGF, E, false , Dest, Ptr, Val1, Val2,
545- FailureOrder, Size, Order, Scope);
556+ ExpectedResult, FailureOrder, Size, Order, Scope);
546557 return ;
547558 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
548559 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
549560 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
550561 emitAtomicCmpXchgFailureSet (CGF, E, true , Dest, Ptr, Val1, Val2,
551- FailureOrder, Size, Order, Scope);
562+ ExpectedResult, FailureOrder, Size, Order, Scope);
552563 return ;
553564 case AtomicExpr::AO__atomic_compare_exchange:
554565 case AtomicExpr::AO__atomic_compare_exchange_n:
555566 case AtomicExpr::AO__scoped_atomic_compare_exchange:
556567 case AtomicExpr::AO__scoped_atomic_compare_exchange_n: {
557568 if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) {
558569 emitAtomicCmpXchgFailureSet (CGF, E, IsWeakC->getZExtValue (), Dest, Ptr,
559- Val1, Val2, FailureOrder, Size, Order, Scope);
570+ Val1, Val2, ExpectedResult, FailureOrder, Size, Order, Scope);
560571 } else {
561572 // Create all the relevant BB's
562573 llvm::BasicBlock *StrongBB =
@@ -570,12 +581,12 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
570581
571582 CGF.Builder .SetInsertPoint (StrongBB);
572583 emitAtomicCmpXchgFailureSet (CGF, E, false , Dest, Ptr, Val1, Val2,
573- FailureOrder, Size, Order, Scope);
584+ ExpectedResult, FailureOrder, Size, Order, Scope);
574585 CGF.Builder .CreateBr (ContBB);
575586
576587 CGF.Builder .SetInsertPoint (WeakBB);
577588 emitAtomicCmpXchgFailureSet (CGF, E, true , Dest, Ptr, Val1, Val2,
578- FailureOrder, Size, Order, Scope);
589+ ExpectedResult, FailureOrder, Size, Order, Scope);
579590 CGF.Builder .CreateBr (ContBB);
580591
581592 CGF.Builder .SetInsertPoint (ContBB);
@@ -785,6 +796,7 @@ EmitValToTemp(CodeGenFunction &CGF, Expr *E) {
785796
786797static void EmitAtomicOp (CodeGenFunction &CGF, AtomicExpr *Expr, Address Dest,
787798 Address Ptr, Address Val1, Address Val2,
799+ Address OriginalVal1,
788800 llvm::Value *IsWeak, llvm::Value *FailureOrder,
789801 uint64_t Size, llvm::AtomicOrdering Order,
790802 llvm::Value *Scope) {
@@ -804,7 +816,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *Expr, Address Dest,
804816 Order, CGF.getLLVMContext ());
805817 else
806818 SS = llvm::SyncScope::System;
807- EmitAtomicOp (CGF, Expr, Dest, Ptr, Val1, Val2, IsWeak, FailureOrder, Size,
819+ EmitAtomicOp (CGF, Expr, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, FailureOrder, Size,
808820 Order, SS);
809821 return ;
810822 }
@@ -814,7 +826,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *Expr, Address Dest,
814826 auto SCID = CGF.getTargetHooks ().getLLVMSyncScopeID (
815827 CGF.CGM .getLangOpts (), ScopeModel->map (SC->getZExtValue ()),
816828 Order, CGF.CGM .getLLVMContext ());
817- EmitAtomicOp (CGF, Expr, Dest, Ptr, Val1, Val2, IsWeak, FailureOrder, Size,
829+ EmitAtomicOp (CGF, Expr, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, FailureOrder, Size,
818830 Order, SCID);
819831 return ;
820832 }
@@ -840,7 +852,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *Expr, Address Dest,
840852 SI->addCase (Builder.getInt32 (S), B);
841853
842854 Builder.SetInsertPoint (B);
843- EmitAtomicOp (CGF, Expr, Dest, Ptr, Val1, Val2, IsWeak, FailureOrder, Size,
855+ EmitAtomicOp (CGF, Expr, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, FailureOrder, Size,
844856 Order,
845857 CGF.getTargetHooks ().getLLVMSyncScopeID (CGF.CGM .getLangOpts (),
846858 ScopeModel->map (S),
@@ -1046,6 +1058,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
10461058 LValue AtomicVal = MakeAddrLValue (Ptr, AtomicTy);
10471059 AtomicInfo Atomics (*this , AtomicVal);
10481060
1061+ Address OriginalVal1 = Val1;
10491062 if (ShouldCastToIntPtrTy) {
10501063 Ptr = Atomics.castToAtomicIntPointer (Ptr);
10511064 if (Val1.isValid ())
@@ -1289,30 +1302,30 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
12891302 if (llvm::isValidAtomicOrderingCABI (ord))
12901303 switch ((llvm::AtomicOrderingCABI)ord) {
12911304 case llvm::AtomicOrderingCABI::relaxed:
1292- EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1305+ EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail, Size,
12931306 llvm::AtomicOrdering::Monotonic, Scope);
12941307 break ;
12951308 case llvm::AtomicOrderingCABI::consume:
12961309 case llvm::AtomicOrderingCABI::acquire:
12971310 if (IsStore)
12981311 break ; // Avoid crashing on code with undefined behavior
1299- EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1312+ EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail, Size,
13001313 llvm::AtomicOrdering::Acquire, Scope);
13011314 break ;
13021315 case llvm::AtomicOrderingCABI::release:
13031316 if (IsLoad)
13041317 break ; // Avoid crashing on code with undefined behavior
1305- EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1318+ EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail, Size,
13061319 llvm::AtomicOrdering::Release, Scope);
13071320 break ;
13081321 case llvm::AtomicOrderingCABI::acq_rel:
13091322 if (IsLoad || IsStore)
13101323 break ; // Avoid crashing on code with undefined behavior
1311- EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1324+ EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail, Size,
13121325 llvm::AtomicOrdering::AcquireRelease, Scope);
13131326 break ;
13141327 case llvm::AtomicOrderingCABI::seq_cst:
1315- EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1328+ EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail, Size,
13161329 llvm::AtomicOrdering::SequentiallyConsistent, Scope);
13171330 break ;
13181331 }
@@ -1348,12 +1361,12 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
13481361
13491362 // Emit all the different atomics
13501363 Builder.SetInsertPoint (MonotonicBB);
1351- EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1364+ EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail, Size,
13521365 llvm::AtomicOrdering::Monotonic, Scope);
13531366 Builder.CreateBr (ContBB);
13541367 if (!IsStore) {
13551368 Builder.SetInsertPoint (AcquireBB);
1356- EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1369+ EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail, Size,
13571370 llvm::AtomicOrdering::Acquire, Scope);
13581371 Builder.CreateBr (ContBB);
13591372 SI->addCase (Builder.getInt32 ((int )llvm::AtomicOrderingCABI::consume),
@@ -1363,22 +1376,22 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
13631376 }
13641377 if (!IsLoad) {
13651378 Builder.SetInsertPoint (ReleaseBB);
1366- EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1379+ EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail, Size,
13671380 llvm::AtomicOrdering::Release, Scope);
13681381 Builder.CreateBr (ContBB);
13691382 SI->addCase (Builder.getInt32 ((int )llvm::AtomicOrderingCABI::release),
13701383 ReleaseBB);
13711384 }
13721385 if (!IsLoad && !IsStore) {
13731386 Builder.SetInsertPoint (AcqRelBB);
1374- EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1387+ EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail, Size,
13751388 llvm::AtomicOrdering::AcquireRelease, Scope);
13761389 Builder.CreateBr (ContBB);
13771390 SI->addCase (Builder.getInt32 ((int )llvm::AtomicOrderingCABI::acq_rel),
13781391 AcqRelBB);
13791392 }
13801393 Builder.SetInsertPoint (SeqCstBB);
1381- EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, Size,
1394+ EmitAtomicOp (*this , E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail, Size,
13821395 llvm::AtomicOrdering::SequentiallyConsistent, Scope);
13831396 Builder.CreateBr (ContBB);
13841397 SI->addCase (Builder.getInt32 ((int )llvm::AtomicOrderingCABI::seq_cst),
0 commit comments