Skip to content

Commit 35c7df1

Browse files
authored
[aarch64][arm] Add support for the _Interlocked[Compare]ExchangePointer_{acq|nf|rel} MS intrinsics (llvm#117645)
Adds support for the following MSVC intrinsics: * `_InterlockedCompareExchangePointer_acq` * `_InterlockedCompareExchangePointer_rel` * `_InterlockedExchangePointer_acq` * `_InterlockedExchangePointer_nf` * `_InterlockedExchangePointer_rel` These are documented at: <https://learn.microsoft.com/en-us/cpp/intrinsics/arm64-intrinsics?view=msvc-170#interlocked-intrinsics> NOTE: `_InterlockedCompareExchangePointer_nf` is not being added since it already exists, although it was incorrectly added for all architectures instead of being Arm & AArch64 specific. This change also unifies how the pointer and non-pointer interlocked compare-exchange intrinsics are being handled.
1 parent a7da702 commit 35c7df1

File tree

5 files changed

+120
-30
lines changed

5 files changed

+120
-30
lines changed

clang/include/clang/Basic/BuiltinsAArch64.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ TARGET_HEADER_BUILTIN(_InterlockedExchange_rel, "NiNiD*Ni", "nh", INTRIN_H,
182182
TARGET_HEADER_BUILTIN(_InterlockedExchange64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
183183
TARGET_HEADER_BUILTIN(_InterlockedExchange64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
184184
TARGET_HEADER_BUILTIN(_InterlockedExchange64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
185+
TARGET_HEADER_BUILTIN(_InterlockedExchangePointer_acq, "v*v*D*v*","nh", INTRIN_H, ALL_MS_LANGUAGES, "")
186+
TARGET_HEADER_BUILTIN(_InterlockedExchangePointer_nf, "v*v*D*v*","nh", INTRIN_H, ALL_MS_LANGUAGES, "")
187+
TARGET_HEADER_BUILTIN(_InterlockedExchangePointer_rel, "v*v*D*v*","nh", INTRIN_H, ALL_MS_LANGUAGES, "")
185188

186189
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_acq, "ccD*cc", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
187190
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_nf, "ccD*cc", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
@@ -195,6 +198,8 @@ TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_rel, "NiNiD*NiNi", "nh",
195198
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_acq, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
196199
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_nf, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
197200
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_rel, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
201+
TARGET_HEADER_BUILTIN(_InterlockedCompareExchangePointer_acq, "v*v*D*v*v*","nh", INTRIN_H, ALL_MS_LANGUAGES, "")
202+
TARGET_HEADER_BUILTIN(_InterlockedCompareExchangePointer_rel, "v*v*D*v*v*","nh", INTRIN_H, ALL_MS_LANGUAGES, "")
198203

199204
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
200205
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128_acq,"UcLLiD*LLiLLiLLi*", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")

clang/include/clang/Basic/BuiltinsARM.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ TARGET_HEADER_BUILTIN(_InterlockedExchange_rel, "NiNiD*Ni", "nh", INTRIN_H,
270270
TARGET_HEADER_BUILTIN(_InterlockedExchange64_acq, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
271271
TARGET_HEADER_BUILTIN(_InterlockedExchange64_nf, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
272272
TARGET_HEADER_BUILTIN(_InterlockedExchange64_rel, "LLiLLiD*LLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
273+
TARGET_HEADER_BUILTIN(_InterlockedExchangePointer_acq, "v*v*D*v*","nh", INTRIN_H, ALL_MS_LANGUAGES, "")
274+
TARGET_HEADER_BUILTIN(_InterlockedExchangePointer_nf, "v*v*D*v*","nh", INTRIN_H, ALL_MS_LANGUAGES, "")
275+
TARGET_HEADER_BUILTIN(_InterlockedExchangePointer_rel, "v*v*D*v*","nh", INTRIN_H, ALL_MS_LANGUAGES, "")
273276

274277
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_acq, "ccD*cc", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
275278
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange8_nf, "ccD*cc", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
@@ -283,6 +286,8 @@ TARGET_HEADER_BUILTIN(_InterlockedCompareExchange_rel, "NiNiD*NiNi", "nh",
283286
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_acq, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
284287
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_nf, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
285288
TARGET_HEADER_BUILTIN(_InterlockedCompareExchange64_rel, "LLiLLiD*LLiLLi", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
289+
TARGET_HEADER_BUILTIN(_InterlockedCompareExchangePointer_acq, "v*v*D*v*v*","nh", INTRIN_H, ALL_MS_LANGUAGES, "")
290+
TARGET_HEADER_BUILTIN(_InterlockedCompareExchangePointer_rel, "v*v*D*v*v*","nh", INTRIN_H, ALL_MS_LANGUAGES, "")
286291

287292
TARGET_HEADER_BUILTIN(_InterlockedOr8_acq, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")
288293
TARGET_HEADER_BUILTIN(_InterlockedOr8_nf, "ccD*c", "nh", INTRIN_H, ALL_MS_LANGUAGES, "")

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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:

clang/lib/Headers/intrin0.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,9 @@ long _InterlockedExchange_rel(long volatile *_Target, long _Value);
207207
__int64 _InterlockedExchange64_acq(__int64 volatile *_Target, __int64 _Value);
208208
__int64 _InterlockedExchange64_nf(__int64 volatile *_Target, __int64 _Value);
209209
__int64 _InterlockedExchange64_rel(__int64 volatile *_Target, __int64 _Value);
210+
void *_InterlockedExchangePointer_acq(void *volatile *_Target, void *_Value);
211+
void *_InterlockedExchangePointer_nf(void *volatile *_Target, void *_Value);
212+
void *_InterlockedExchangePointer_rel(void *volatile *_Target, void *_Value);
210213

211214
/*----------------------------------------------------------------------------*\
212215
|* Interlocked Compare Exchange
@@ -237,6 +240,12 @@ __int64 _InterlockedCompareExchange64_nf(__int64 volatile *_Destination,
237240
__int64 _InterlockedCompareExchange64_rel(__int64 volatile *_Destination,
238241
__int64 _Exchange,
239242
__int64 _Comparand);
243+
void *_InterlockedCompareExchangePointer_acq(void *volatile *_Destination,
244+
void *_Exchange, void *_Comparand);
245+
void *_InterlockedCompareExchangePointer_nf(void *volatile *_Destination,
246+
void *_Exchange, void *_Comparand);
247+
void *_InterlockedCompareExchangePointer_rel(void *volatile *_Destination,
248+
void *_Exchange, void *_Comparand);
240249
#endif
241250

242251
#ifdef __cplusplus

clang/test/CodeGen/ms-intrinsics.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,41 @@ void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) {
221221
// CHECK: ret ptr %[[RESULT]]
222222
// CHECK: }
223223

224+
#if defined(__arm__) || defined(__aarch64__)
225+
void *test_InterlockedExchangePointer_acq(void * volatile *Target, void *Value) {
226+
return _InterlockedExchangePointer_acq(Target, Value);
227+
}
228+
229+
// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedExchangePointer_acq(ptr {{[a-z_ ]*}}%Target, ptr {{[a-z_ ]*}}%Value){{.*}}{
230+
// CHECK-ARM-ARM64: %[[VALUE:[0-9]+]] = ptrtoint ptr %Value to [[iPTR:i[0-9]+]]
231+
// CHECK-ARM-ARM64: %[[EXCHANGE:[0-9]+]] = atomicrmw xchg ptr %Target, [[iPTR]] %[[VALUE]] acquire, align {{4|8}}
232+
// CHECK-ARM-ARM64: %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXCHANGE]] to ptr
233+
// CHECK-ARM-ARM64: ret ptr %[[RESULT]]
234+
// CHECK-ARM-ARM64: }
235+
236+
void *test_InterlockedExchangePointer_nf(void * volatile *Target, void *Value) {
237+
return _InterlockedExchangePointer_nf(Target, Value);
238+
}
239+
240+
// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedExchangePointer_nf(ptr {{[a-z_ ]*}}%Target, ptr {{[a-z_ ]*}}%Value){{.*}}{
241+
// CHECK-ARM-ARM64: %[[VALUE:[0-9]+]] = ptrtoint ptr %Value to [[iPTR]]
242+
// CHECK-ARM-ARM64: %[[EXCHANGE:[0-9]+]] = atomicrmw xchg ptr %Target, [[iPTR]] %[[VALUE]] monotonic, align {{4|8}}
243+
// CHECK-ARM-ARM64: %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXCHANGE]] to ptr
244+
// CHECK-ARM-ARM64: ret ptr %[[RESULT]]
245+
// CHECK-ARM-ARM64: }
246+
247+
void *test_InterlockedExchangePointer_rel(void * volatile *Target, void *Value) {
248+
return _InterlockedExchangePointer_rel(Target, Value);
249+
}
250+
251+
// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedExchangePointer_rel(ptr {{[a-z_ ]*}}%Target, ptr {{[a-z_ ]*}}%Value){{.*}}{
252+
// CHECK-ARM-ARM64: %[[VALUE:[0-9]+]] = ptrtoint ptr %Value to [[iPTR]]
253+
// CHECK-ARM-ARM64: %[[EXCHANGE:[0-9]+]] = atomicrmw xchg ptr %Target, [[iPTR]] %[[VALUE]] release, align {{4|8}}
254+
// CHECK-ARM-ARM64: %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXCHANGE]] to ptr
255+
// CHECK-ARM-ARM64: ret ptr %[[RESULT]]
256+
// CHECK-ARM-ARM64: }
257+
#endif
258+
224259
void *test_InterlockedCompareExchangePointer(void * volatile *Destination,
225260
void *Exchange, void *Comparand) {
226261
return _InterlockedCompareExchangePointer(Destination, Exchange, Comparand);
@@ -249,6 +284,37 @@ void *test_InterlockedCompareExchangePointer_nf(void * volatile *Destination,
249284
// CHECK: ret ptr %[[RESULT:[0-9]+]]
250285
// CHECK: }
251286

287+
#if defined(__arm__) || defined(__aarch64__)
288+
void *test_InterlockedCompareExchangePointer_acq(void * volatile *Destination,
289+
void *Exchange, void *Comparand) {
290+
return _InterlockedCompareExchangePointer_acq(Destination, Exchange, Comparand);
291+
}
292+
293+
// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedCompareExchangePointer_acq(ptr {{[a-z_ ]*}}%Destination, ptr {{[a-z_ ]*}}%Exchange, ptr {{[a-z_ ]*}}%Comparand){{.*}}{
294+
// CHECK-ARM-ARM64: %[[EXCHANGE:[0-9]+]] = ptrtoint ptr %Exchange to [[iPTR]]
295+
// CHECK-ARM-ARM64: %[[COMPARAND:[0-9]+]] = ptrtoint ptr %Comparand to [[iPTR]]
296+
// CHECK-ARM-ARM64: %[[XCHG:[0-9]+]] = cmpxchg volatile ptr %[[DEST:.+]], [[iPTR]] %[[COMPARAND:[0-9]+]], [[iPTR]] %[[EXCHANGE:[0-9]+]] acquire acquire, align {{4|8}}
297+
// CHECK-ARM-ARM64: %[[EXTRACT:[0-9]+]] = extractvalue { [[iPTR]], i1 } %[[XCHG]], 0
298+
// CHECK-ARM-ARM64: %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXTRACT]] to ptr
299+
// CHECK-ARM-ARM64: ret ptr %[[RESULT:[0-9]+]]
300+
// CHECK-ARM-ARM64: }
301+
302+
303+
void *test_InterlockedCompareExchangePointer_rel(void * volatile *Destination,
304+
void *Exchange, void *Comparand) {
305+
return _InterlockedCompareExchangePointer_rel(Destination, Exchange, Comparand);
306+
}
307+
308+
// CHECK-ARM-ARM64: define{{.*}}ptr @test_InterlockedCompareExchangePointer_rel(ptr {{[a-z_ ]*}}%Destination, ptr {{[a-z_ ]*}}%Exchange, ptr {{[a-z_ ]*}}%Comparand){{.*}}{
309+
// CHECK-ARM-ARM64: %[[EXCHANGE:[0-9]+]] = ptrtoint ptr %Exchange to [[iPTR]]
310+
// CHECK-ARM-ARM64: %[[COMPARAND:[0-9]+]] = ptrtoint ptr %Comparand to [[iPTR]]
311+
// CHECK-ARM-ARM64: %[[XCHG:[0-9]+]] = cmpxchg volatile ptr %[[DEST:.+]], [[iPTR]] %[[COMPARAND:[0-9]+]], [[iPTR]] %[[EXCHANGE:[0-9]+]] release monotonic, align {{4|8}}
312+
// CHECK-ARM-ARM64: %[[EXTRACT:[0-9]+]] = extractvalue { [[iPTR]], i1 } %[[XCHG]], 0
313+
// CHECK-ARM-ARM64: %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXTRACT]] to ptr
314+
// CHECK-ARM-ARM64: ret ptr %[[RESULT:[0-9]+]]
315+
// CHECK-ARM-ARM64: }
316+
#endif
317+
252318
char test_InterlockedExchange8(char volatile *value, char mask) {
253319
return _InterlockedExchange8(value, mask);
254320
}

0 commit comments

Comments
 (0)