@@ -522,8 +522,15 @@ Value *EmitAtomicCmpXchgForMSIntrin(CodeGenFunction &CGF, const CallExpr *E,
522522
523523 Address DestAddr = CheckAtomicAlignment(CGF, E);
524524
525- auto *Comparand = CGF.EmitScalarExpr(E->getArg(2));
526525 auto *Exchange = CGF.EmitScalarExpr(E->getArg(1));
526+ auto *RTy = Exchange->getType();
527+
528+ auto *Comparand = CGF.EmitScalarExpr(E->getArg(2));
529+
530+ if (RTy->isPointerTy()) {
531+ Exchange = CGF.Builder.CreatePtrToInt(Exchange, CGF.IntPtrTy);
532+ Comparand = CGF.Builder.CreatePtrToInt(Comparand, CGF.IntPtrTy);
533+ }
527534
528535 // For Release ordering, the failure ordering should be Monotonic.
529536 auto FailureOrdering = SuccessOrdering == AtomicOrdering::Release ?
@@ -534,10 +541,16 @@ Value *EmitAtomicCmpXchgForMSIntrin(CodeGenFunction &CGF, const CallExpr *E,
534541 // blocks the few atomics optimizations that LLVM has. If we want to optimize
535542 // _Interlocked* operations in the future, we will have to remove the volatile
536543 // marker.
537- auto *Result = CGF.Builder.CreateAtomicCmpXchg(
544+ auto *CmpXchg = CGF.Builder.CreateAtomicCmpXchg(
538545 DestAddr, Comparand, Exchange, SuccessOrdering, FailureOrdering);
539- Result->setVolatile(true);
540- return CGF.Builder.CreateExtractValue(Result, 0);
546+ CmpXchg->setVolatile(true);
547+
548+ auto *Result = CGF.Builder.CreateExtractValue(CmpXchg, 0);
549+ if (RTy->isPointerTy()) {
550+ Result = CGF.Builder.CreateIntToPtr(Result, RTy);
551+ }
552+
553+ return Result;
541554}
542555
543556// 64-bit Microsoft platforms support 128 bit cmpxchg operations. They are
@@ -1620,6 +1633,7 @@ enum class CodeGenFunction::MSVCIntrin {
16201633 _BitScanForward,
16211634 _BitScanReverse,
16221635 _InterlockedAnd,
1636+ _InterlockedCompareExchange,
16231637 _InterlockedDecrement,
16241638 _InterlockedExchange,
16251639 _InterlockedExchangeAdd,
@@ -1705,26 +1719,31 @@ translateArmToMsvcIntrin(unsigned BuiltinID) {
17051719 case clang::ARM::BI_InterlockedExchange16_acq:
17061720 case clang::ARM::BI_InterlockedExchange_acq:
17071721 case clang::ARM::BI_InterlockedExchange64_acq:
1722+ case clang::ARM::BI_InterlockedExchangePointer_acq:
17081723 return MSVCIntrin::_InterlockedExchange_acq;
17091724 case clang::ARM::BI_InterlockedExchange8_rel:
17101725 case clang::ARM::BI_InterlockedExchange16_rel:
17111726 case clang::ARM::BI_InterlockedExchange_rel:
17121727 case clang::ARM::BI_InterlockedExchange64_rel:
1728+ case clang::ARM::BI_InterlockedExchangePointer_rel:
17131729 return MSVCIntrin::_InterlockedExchange_rel;
17141730 case clang::ARM::BI_InterlockedExchange8_nf:
17151731 case clang::ARM::BI_InterlockedExchange16_nf:
17161732 case clang::ARM::BI_InterlockedExchange_nf:
17171733 case clang::ARM::BI_InterlockedExchange64_nf:
1734+ case clang::ARM::BI_InterlockedExchangePointer_nf:
17181735 return MSVCIntrin::_InterlockedExchange_nf;
17191736 case clang::ARM::BI_InterlockedCompareExchange8_acq:
17201737 case clang::ARM::BI_InterlockedCompareExchange16_acq:
17211738 case clang::ARM::BI_InterlockedCompareExchange_acq:
17221739 case clang::ARM::BI_InterlockedCompareExchange64_acq:
1740+ case clang::ARM::BI_InterlockedCompareExchangePointer_acq:
17231741 return MSVCIntrin::_InterlockedCompareExchange_acq;
17241742 case clang::ARM::BI_InterlockedCompareExchange8_rel:
17251743 case clang::ARM::BI_InterlockedCompareExchange16_rel:
17261744 case clang::ARM::BI_InterlockedCompareExchange_rel:
17271745 case clang::ARM::BI_InterlockedCompareExchange64_rel:
1746+ case clang::ARM::BI_InterlockedCompareExchangePointer_rel:
17281747 return MSVCIntrin::_InterlockedCompareExchange_rel;
17291748 case clang::ARM::BI_InterlockedCompareExchange8_nf:
17301749 case clang::ARM::BI_InterlockedCompareExchange16_nf:
@@ -1851,26 +1870,31 @@ translateAarch64ToMsvcIntrin(unsigned BuiltinID) {
18511870 case clang::AArch64::BI_InterlockedExchange16_acq:
18521871 case clang::AArch64::BI_InterlockedExchange_acq:
18531872 case clang::AArch64::BI_InterlockedExchange64_acq:
1873+ case clang::AArch64::BI_InterlockedExchangePointer_acq:
18541874 return MSVCIntrin::_InterlockedExchange_acq;
18551875 case clang::AArch64::BI_InterlockedExchange8_rel:
18561876 case clang::AArch64::BI_InterlockedExchange16_rel:
18571877 case clang::AArch64::BI_InterlockedExchange_rel:
18581878 case clang::AArch64::BI_InterlockedExchange64_rel:
1879+ case clang::AArch64::BI_InterlockedExchangePointer_rel:
18591880 return MSVCIntrin::_InterlockedExchange_rel;
18601881 case clang::AArch64::BI_InterlockedExchange8_nf:
18611882 case clang::AArch64::BI_InterlockedExchange16_nf:
18621883 case clang::AArch64::BI_InterlockedExchange_nf:
18631884 case clang::AArch64::BI_InterlockedExchange64_nf:
1885+ case clang::AArch64::BI_InterlockedExchangePointer_nf:
18641886 return MSVCIntrin::_InterlockedExchange_nf;
18651887 case clang::AArch64::BI_InterlockedCompareExchange8_acq:
18661888 case clang::AArch64::BI_InterlockedCompareExchange16_acq:
18671889 case clang::AArch64::BI_InterlockedCompareExchange_acq:
18681890 case clang::AArch64::BI_InterlockedCompareExchange64_acq:
1891+ case clang::AArch64::BI_InterlockedCompareExchangePointer_acq:
18691892 return MSVCIntrin::_InterlockedCompareExchange_acq;
18701893 case clang::AArch64::BI_InterlockedCompareExchange8_rel:
18711894 case clang::AArch64::BI_InterlockedCompareExchange16_rel:
18721895 case clang::AArch64::BI_InterlockedCompareExchange_rel:
18731896 case clang::AArch64::BI_InterlockedCompareExchange64_rel:
1897+ case clang::AArch64::BI_InterlockedCompareExchangePointer_rel:
18741898 return MSVCIntrin::_InterlockedCompareExchange_rel;
18751899 case clang::AArch64::BI_InterlockedCompareExchange8_nf:
18761900 case clang::AArch64::BI_InterlockedCompareExchange16_nf:
@@ -2073,6 +2097,8 @@ Value *CodeGenFunction::EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID,
20732097 case MSVCIntrin::_InterlockedExchange_nf:
20742098 return MakeBinaryAtomicValue(*this, AtomicRMWInst::Xchg, E,
20752099 AtomicOrdering::Monotonic);
2100+ case MSVCIntrin::_InterlockedCompareExchange:
2101+ return EmitAtomicCmpXchgForMSIntrin(*this, E);
20762102 case MSVCIntrin::_InterlockedCompareExchange_acq:
20772103 return EmitAtomicCmpXchgForMSIntrin(*this, E, AtomicOrdering::Acquire);
20782104 case MSVCIntrin::_InterlockedCompareExchange_rel:
@@ -5720,32 +5746,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
57205746 return RValue::get(
57215747 EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedExchange, E));
57225748 case Builtin::BI_InterlockedCompareExchangePointer:
5723- case Builtin::BI_InterlockedCompareExchangePointer_nf: {
5724- llvm::Type *RTy;
5725- llvm::IntegerType *IntType = IntegerType::get(
5726- getLLVMContext(), getContext().getTypeSize(E->getType()));
5727-
5728- Address DestAddr = CheckAtomicAlignment(*this, E);
5729-
5730- llvm::Value *Exchange = EmitScalarExpr(E->getArg(1));
5731- RTy = Exchange->getType();
5732- Exchange = Builder.CreatePtrToInt(Exchange, IntType);
5733-
5734- llvm::Value *Comparand =
5735- Builder.CreatePtrToInt(EmitScalarExpr(E->getArg(2)), IntType);
5736-
5737- auto Ordering =
5738- BuiltinID == Builtin::BI_InterlockedCompareExchangePointer_nf ?
5739- AtomicOrdering::Monotonic : AtomicOrdering::SequentiallyConsistent;
5740-
5741- auto Result = Builder.CreateAtomicCmpXchg(DestAddr, Comparand, Exchange,
5742- Ordering, Ordering);
5743- Result->setVolatile(true);
5744-
5745- return RValue::get(Builder.CreateIntToPtr(Builder.CreateExtractValue(Result,
5746- 0),
5747- RTy));
5748- }
5749+ return RValue::get(
5750+ EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedCompareExchange, E));
5751+ case Builtin::BI_InterlockedCompareExchangePointer_nf:
5752+ return RValue::get(
5753+ EmitMSVCBuiltinExpr(MSVCIntrin::_InterlockedCompareExchange_nf, E));
57495754 case Builtin::BI_InterlockedCompareExchange8:
57505755 case Builtin::BI_InterlockedCompareExchange16:
57515756 case Builtin::BI_InterlockedCompareExchange:
0 commit comments