@@ -376,6 +376,7 @@ bool AtomicInfo::emitMemSetZeroIfNecessary() const {
376
376
static void emitAtomicCmpXchg (CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
377
377
Address Dest, Address Ptr,
378
378
Address Val1, Address Val2,
379
+ Address ExpectedResult,
379
380
uint64_t Size,
380
381
llvm::AtomicOrdering SuccessOrder,
381
382
llvm::AtomicOrdering FailureOrder,
@@ -411,9 +412,17 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
411
412
412
413
CGF.Builder .SetInsertPoint (StoreExpectedBB);
413
414
// Update the memory at Expected with Old's value.
414
- auto *I = CGF.Builder .CreateStore (Old, Val1);
415
- CGF.addInstToCurrentSourceAtom (I, Old);
416
415
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
+ }
417
426
// Finally, branch to the exit point.
418
427
CGF.Builder .CreateBr (ContinueBB);
419
428
@@ -428,6 +437,7 @@ static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
428
437
static void emitAtomicCmpXchgFailureSet (CodeGenFunction &CGF, AtomicExpr *E,
429
438
bool IsWeak, Address Dest, Address Ptr,
430
439
Address Val1, Address Val2,
440
+ Address ExpectedResult,
431
441
llvm::Value *FailureOrderVal,
432
442
uint64_t Size,
433
443
llvm::AtomicOrdering SuccessOrder,
@@ -458,7 +468,7 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
458
468
// success argument". This condition has been lifted and the only
459
469
// precondition is 31.7.2.18. Effectively treat this as a DR and skip
460
470
// 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,
462
472
FailureOrder, Scope);
463
473
return ;
464
474
}
@@ -483,17 +493,17 @@ static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
483
493
484
494
// Emit all the different atomics
485
495
CGF.Builder .SetInsertPoint (MonotonicBB);
486
- emitAtomicCmpXchg (CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
496
+ emitAtomicCmpXchg (CGF, E, IsWeak, Dest, Ptr, Val1, Val2, ExpectedResult,
487
497
Size, SuccessOrder, llvm::AtomicOrdering::Monotonic, Scope);
488
498
CGF.Builder .CreateBr (ContBB);
489
499
490
500
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,
492
502
llvm::AtomicOrdering::Acquire, Scope);
493
503
CGF.Builder .CreateBr (ContBB);
494
504
495
505
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,
497
507
llvm::AtomicOrdering::SequentiallyConsistent, Scope);
498
508
CGF.Builder .CreateBr (ContBB);
499
509
@@ -526,6 +536,7 @@ static llvm::Value *EmitPostAtomicMinMax(CGBuilderTy &Builder,
526
536
527
537
static void EmitAtomicOp (CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
528
538
Address Ptr, Address Val1, Address Val2,
539
+ Address ExpectedResult,
529
540
llvm::Value *IsWeak, llvm::Value *FailureOrder,
530
541
uint64_t Size, llvm::AtomicOrdering Order,
531
542
llvm::SyncScope::ID Scope) {
@@ -542,21 +553,21 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
542
553
case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
543
554
case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
544
555
emitAtomicCmpXchgFailureSet (CGF, E, false , Dest, Ptr, Val1, Val2,
545
- FailureOrder, Size, Order, Scope);
556
+ ExpectedResult, FailureOrder, Size, Order, Scope);
546
557
return ;
547
558
case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
548
559
case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
549
560
case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
550
561
emitAtomicCmpXchgFailureSet (CGF, E, true , Dest, Ptr, Val1, Val2,
551
- FailureOrder, Size, Order, Scope);
562
+ ExpectedResult, FailureOrder, Size, Order, Scope);
552
563
return ;
553
564
case AtomicExpr::AO__atomic_compare_exchange:
554
565
case AtomicExpr::AO__atomic_compare_exchange_n:
555
566
case AtomicExpr::AO__scoped_atomic_compare_exchange:
556
567
case AtomicExpr::AO__scoped_atomic_compare_exchange_n: {
557
568
if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) {
558
569
emitAtomicCmpXchgFailureSet (CGF, E, IsWeakC->getZExtValue (), Dest, Ptr,
559
- Val1, Val2, FailureOrder, Size, Order, Scope);
570
+ Val1, Val2, ExpectedResult, FailureOrder, Size, Order, Scope);
560
571
} else {
561
572
// Create all the relevant BB's
562
573
llvm::BasicBlock *StrongBB =
@@ -570,12 +581,12 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest,
570
581
571
582
CGF.Builder .SetInsertPoint (StrongBB);
572
583
emitAtomicCmpXchgFailureSet (CGF, E, false , Dest, Ptr, Val1, Val2,
573
- FailureOrder, Size, Order, Scope);
584
+ ExpectedResult, FailureOrder, Size, Order, Scope);
574
585
CGF.Builder .CreateBr (ContBB);
575
586
576
587
CGF.Builder .SetInsertPoint (WeakBB);
577
588
emitAtomicCmpXchgFailureSet (CGF, E, true , Dest, Ptr, Val1, Val2,
578
- FailureOrder, Size, Order, Scope);
589
+ ExpectedResult, FailureOrder, Size, Order, Scope);
579
590
CGF.Builder .CreateBr (ContBB);
580
591
581
592
CGF.Builder .SetInsertPoint (ContBB);
@@ -785,6 +796,7 @@ EmitValToTemp(CodeGenFunction &CGF, Expr *E) {
785
796
786
797
static void EmitAtomicOp (CodeGenFunction &CGF, AtomicExpr *Expr, Address Dest,
787
798
Address Ptr, Address Val1, Address Val2,
799
+ Address OriginalVal1,
788
800
llvm::Value *IsWeak, llvm::Value *FailureOrder,
789
801
uint64_t Size, llvm::AtomicOrdering Order,
790
802
llvm::Value *Scope) {
@@ -804,7 +816,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *Expr, Address Dest,
804
816
Order, CGF.getLLVMContext ());
805
817
else
806
818
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,
808
820
Order, SS);
809
821
return ;
810
822
}
@@ -814,7 +826,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *Expr, Address Dest,
814
826
auto SCID = CGF.getTargetHooks ().getLLVMSyncScopeID (
815
827
CGF.CGM .getLangOpts (), ScopeModel->map (SC->getZExtValue ()),
816
828
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,
818
830
Order, SCID);
819
831
return ;
820
832
}
@@ -840,7 +852,7 @@ static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *Expr, Address Dest,
840
852
SI->addCase (Builder.getInt32 (S), B);
841
853
842
854
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,
844
856
Order,
845
857
CGF.getTargetHooks ().getLLVMSyncScopeID (CGF.CGM .getLangOpts (),
846
858
ScopeModel->map (S),
@@ -1046,6 +1058,7 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
1046
1058
LValue AtomicVal = MakeAddrLValue (Ptr, AtomicTy);
1047
1059
AtomicInfo Atomics (*this , AtomicVal);
1048
1060
1061
+ Address OriginalVal1 = Val1;
1049
1062
if (ShouldCastToIntPtrTy) {
1050
1063
Ptr = Atomics.castToAtomicIntPointer (Ptr);
1051
1064
if (Val1.isValid ())
@@ -1289,30 +1302,30 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
1289
1302
if (llvm::isValidAtomicOrderingCABI (ord))
1290
1303
switch ((llvm::AtomicOrderingCABI)ord) {
1291
1304
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,
1293
1306
llvm::AtomicOrdering::Monotonic, Scope);
1294
1307
break ;
1295
1308
case llvm::AtomicOrderingCABI::consume:
1296
1309
case llvm::AtomicOrderingCABI::acquire:
1297
1310
if (IsStore)
1298
1311
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,
1300
1313
llvm::AtomicOrdering::Acquire, Scope);
1301
1314
break ;
1302
1315
case llvm::AtomicOrderingCABI::release:
1303
1316
if (IsLoad)
1304
1317
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,
1306
1319
llvm::AtomicOrdering::Release, Scope);
1307
1320
break ;
1308
1321
case llvm::AtomicOrderingCABI::acq_rel:
1309
1322
if (IsLoad || IsStore)
1310
1323
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,
1312
1325
llvm::AtomicOrdering::AcquireRelease, Scope);
1313
1326
break ;
1314
1327
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,
1316
1329
llvm::AtomicOrdering::SequentiallyConsistent, Scope);
1317
1330
break ;
1318
1331
}
@@ -1348,12 +1361,12 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
1348
1361
1349
1362
// Emit all the different atomics
1350
1363
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,
1352
1365
llvm::AtomicOrdering::Monotonic, Scope);
1353
1366
Builder.CreateBr (ContBB);
1354
1367
if (!IsStore) {
1355
1368
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,
1357
1370
llvm::AtomicOrdering::Acquire, Scope);
1358
1371
Builder.CreateBr (ContBB);
1359
1372
SI->addCase (Builder.getInt32 ((int )llvm::AtomicOrderingCABI::consume),
@@ -1363,22 +1376,22 @@ RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) {
1363
1376
}
1364
1377
if (!IsLoad) {
1365
1378
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,
1367
1380
llvm::AtomicOrdering::Release, Scope);
1368
1381
Builder.CreateBr (ContBB);
1369
1382
SI->addCase (Builder.getInt32 ((int )llvm::AtomicOrderingCABI::release),
1370
1383
ReleaseBB);
1371
1384
}
1372
1385
if (!IsLoad && !IsStore) {
1373
1386
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,
1375
1388
llvm::AtomicOrdering::AcquireRelease, Scope);
1376
1389
Builder.CreateBr (ContBB);
1377
1390
SI->addCase (Builder.getInt32 ((int )llvm::AtomicOrderingCABI::acq_rel),
1378
1391
AcqRelBB);
1379
1392
}
1380
1393
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,
1382
1395
llvm::AtomicOrdering::SequentiallyConsistent, Scope);
1383
1396
Builder.CreateBr (ContBB);
1384
1397
SI->addCase (Builder.getInt32 ((int )llvm::AtomicOrderingCABI::seq_cst),
0 commit comments