@@ -509,8 +509,15 @@ Value *EmitAtomicCmpXchgForMSIntrin(CodeGenFunction &CGF, const CallExpr *E,
509509
510510 Address DestAddr = CheckAtomicAlignment(CGF, E);
511511
512- auto *Comparand = CGF.EmitScalarExpr(E->getArg(2));
513512 auto *Exchange = CGF.EmitScalarExpr(E->getArg(1));
513+ auto *RTy = Exchange->getType();
514+
515+ auto *Comparand = CGF.EmitScalarExpr(E->getArg(2));
516+
517+ if (RTy->isPointerTy()) {
518+ Exchange = CGF.Builder.CreatePtrToInt(Exchange, CGF.IntPtrTy);
519+ Comparand = CGF.Builder.CreatePtrToInt(Comparand, CGF.IntPtrTy);
520+ }
514521
515522 // For Release ordering, the failure ordering should be Monotonic.
516523 auto FailureOrdering = SuccessOrdering == AtomicOrdering::Release ?
@@ -521,10 +528,16 @@ Value *EmitAtomicCmpXchgForMSIntrin(CodeGenFunction &CGF, const CallExpr *E,
521528 // blocks the few atomics optimizations that LLVM has. If we want to optimize
522529 // _Interlocked* operations in the future, we will have to remove the volatile
523530 // marker.
524- auto *Result = CGF.Builder.CreateAtomicCmpXchg(
531+ auto *CmpXchg = CGF.Builder.CreateAtomicCmpXchg(
525532 DestAddr, Comparand, Exchange, SuccessOrdering, FailureOrdering);
526- Result->setVolatile(true);
527- return CGF.Builder.CreateExtractValue(Result, 0);
533+ CmpXchg->setVolatile(true);
534+
535+ auto *Result = CGF.Builder.CreateExtractValue(CmpXchg, 0);
536+ if (RTy->isPointerTy()) {
537+ Result = CGF.Builder.CreateIntToPtr(Result, RTy);
538+ }
539+
540+ return Result;
528541}
529542
530543// 64-bit Microsoft platforms support 128 bit cmpxchg operations. They are
@@ -1595,6 +1608,7 @@ enum class CodeGenFunction::MSVCIntrin {
15951608 _BitScanForward,
15961609 _BitScanReverse,
15971610 _InterlockedAnd,
1611+ _InterlockedCompareExchange,
15981612 _InterlockedDecrement,
15991613 _InterlockedExchange,
16001614 _InterlockedExchangeAdd,
@@ -1680,26 +1694,31 @@ translateArmToMsvcIntrin(unsigned BuiltinID) {
16801694 case clang::ARM::BI_InterlockedExchange16_acq:
16811695 case clang::ARM::BI_InterlockedExchange_acq:
16821696 case clang::ARM::BI_InterlockedExchange64_acq:
1697+ case clang::ARM::BI_InterlockedExchangePointer_acq:
16831698 return MSVCIntrin::_InterlockedExchange_acq;
16841699 case clang::ARM::BI_InterlockedExchange8_rel:
16851700 case clang::ARM::BI_InterlockedExchange16_rel:
16861701 case clang::ARM::BI_InterlockedExchange_rel:
16871702 case clang::ARM::BI_InterlockedExchange64_rel:
1703+ case clang::ARM::BI_InterlockedExchangePointer_rel:
16881704 return MSVCIntrin::_InterlockedExchange_rel;
16891705 case clang::ARM::BI_InterlockedExchange8_nf:
16901706 case clang::ARM::BI_InterlockedExchange16_nf:
16911707 case clang::ARM::BI_InterlockedExchange_nf:
16921708 case clang::ARM::BI_InterlockedExchange64_nf:
1709+ case clang::ARM::BI_InterlockedExchangePointer_nf:
16931710 return MSVCIntrin::_InterlockedExchange_nf;
16941711 case clang::ARM::BI_InterlockedCompareExchange8_acq:
16951712 case clang::ARM::BI_InterlockedCompareExchange16_acq:
16961713 case clang::ARM::BI_InterlockedCompareExchange_acq:
16971714 case clang::ARM::BI_InterlockedCompareExchange64_acq:
1715+ case clang::ARM::BI_InterlockedCompareExchangePointer_acq:
16981716 return MSVCIntrin::_InterlockedCompareExchange_acq;
16991717 case clang::ARM::BI_InterlockedCompareExchange8_rel:
17001718 case clang::ARM::BI_InterlockedCompareExchange16_rel:
17011719 case clang::ARM::BI_InterlockedCompareExchange_rel:
17021720 case clang::ARM::BI_InterlockedCompareExchange64_rel:
1721+ case clang::ARM::BI_InterlockedCompareExchangePointer_rel:
17031722 return MSVCIntrin::_InterlockedCompareExchange_rel;
17041723 case clang::ARM::BI_InterlockedCompareExchange8_nf:
17051724 case clang::ARM::BI_InterlockedCompareExchange16_nf:
@@ -1826,26 +1845,31 @@ translateAarch64ToMsvcIntrin(unsigned BuiltinID) {
18261845 case clang::AArch64::BI_InterlockedExchange16_acq:
18271846 case clang::AArch64::BI_InterlockedExchange_acq:
18281847 case clang::AArch64::BI_InterlockedExchange64_acq:
1848+ case clang::AArch64::BI_InterlockedExchangePointer_acq:
18291849 return MSVCIntrin::_InterlockedExchange_acq;
18301850 case clang::AArch64::BI_InterlockedExchange8_rel:
18311851 case clang::AArch64::BI_InterlockedExchange16_rel:
18321852 case clang::AArch64::BI_InterlockedExchange_rel:
18331853 case clang::AArch64::BI_InterlockedExchange64_rel:
1854+ case clang::AArch64::BI_InterlockedExchangePointer_rel:
18341855 return MSVCIntrin::_InterlockedExchange_rel;
18351856 case clang::AArch64::BI_InterlockedExchange8_nf:
18361857 case clang::AArch64::BI_InterlockedExchange16_nf:
18371858 case clang::AArch64::BI_InterlockedExchange_nf:
18381859 case clang::AArch64::BI_InterlockedExchange64_nf:
1860+ case clang::AArch64::BI_InterlockedExchangePointer_nf:
18391861 return MSVCIntrin::_InterlockedExchange_nf;
18401862 case clang::AArch64::BI_InterlockedCompareExchange8_acq:
18411863 case clang::AArch64::BI_InterlockedCompareExchange16_acq:
18421864 case clang::AArch64::BI_InterlockedCompareExchange_acq:
18431865 case clang::AArch64::BI_InterlockedCompareExchange64_acq:
1866+ case clang::AArch64::BI_InterlockedCompareExchangePointer_acq:
18441867 return MSVCIntrin::_InterlockedCompareExchange_acq;
18451868 case clang::AArch64::BI_InterlockedCompareExchange8_rel:
18461869 case clang::AArch64::BI_InterlockedCompareExchange16_rel:
18471870 case clang::AArch64::BI_InterlockedCompareExchange_rel:
18481871 case clang::AArch64::BI_InterlockedCompareExchange64_rel:
1872+ case clang::AArch64::BI_InterlockedCompareExchangePointer_rel:
18491873 return MSVCIntrin::_InterlockedCompareExchange_rel;
18501874 case clang::AArch64::BI_InterlockedCompareExchange8_nf:
18511875 case clang::AArch64::BI_InterlockedCompareExchange16_nf:
@@ -2048,6 +2072,8 @@ Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
20482072 case MSVCIntrin::_InterlockedExchange_nf:
20492073 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E,
20502074 AtomicOrdering::Monotonic);
2075+ case MSVCIntrin::_InterlockedCompareExchange:
2076+ return EmitAtomicCmpXchgForMSIntrin(*this, E);
20512077 case MSVCIntrin::_InterlockedCompareExchange_acq:
20522078 return EmitAtomicCmpXchgForMSIntrin(*this, E, AtomicOrdering::Acquire);
20532079 case MSVCIntrin::_InterlockedCompareExchange_rel:
@@ -5695,32 +5721,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
56955721 return RValue::get(
56965722 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E));
56975723 case Builtin::BI_InterlockedCompareExchangePointer:
5698- case Builtin::BI_InterlockedCompareExchangePointer_nf: {
5699- llvm::Type *RTy;
5700- llvm::IntegerType *IntType = IntegerType::get(
5701- getLLVMContext(), getContext().getTypeSize(E->getType()));
5702-
5703- Address DestAddr = CheckAtomicAlignment(*this, E);
5704-
5705- llvm::Value *Exchange = EmitScalarExpr(E->getArg(1));
5706- RTy = Exchange->getType();
5707- Exchange = Builder.CreatePtrToInt(Exchange, IntType);
5708-
5709- llvm::Value *Comparand =
5710- Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType);
5711-
5712- auto Ordering =
5713- BuiltinID == Builtin::BI_InterlockedCompareExchangePointer_nf ?
5714- AtomicOrdering::Monotonic : AtomicOrdering::SequentiallyConsistent;
5715-
5716- auto Result = Builder.CreateAtomicCmpXchg(DestAddr, Comparand, Exchange,
5717- Ordering, Ordering);
5718- Result->setVolatile(true);
5719-
5720- return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result,
5721- 0),
5722- RTy));
5723- }
5724+ return RValue::get(
5725+ EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedCompareExchange, E));
5726+ case Builtin::BI_InterlockedCompareExchangePointer_nf:
5727+ return RValue::get(
5728+ EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedCompareExchange_nf, E));
57245729 case Builtin::BI_InterlockedCompareExchange8:
57255730 case Builtin::BI_InterlockedCompareExchange16:
57265731 case Builtin::BI_InterlockedCompareExchange:
0 commit comments