diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs
index 15a9cc87b7e6..520bdb718a83 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs
@@ -57,6 +57,7 @@ public static partial class Interlocked
/// The value to which the parameter is set.
/// The original value of .
/// The address of location1 is a null pointer.
+ [Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern long Exchange(ref long location1, long value);
@@ -117,6 +118,7 @@ public static partial class Interlocked
/// The value that is compared to the value at .
/// The original value in .
/// The address of is a null pointer.
+ [Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern long CompareExchange(ref long location1, long value, long comparand);
@@ -192,6 +194,7 @@ public static partial class Interlocked
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int ExchangeAdd(ref int location1, int value);
+ [Intrinsic]
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern long ExchangeAdd(ref long location1, long value);
#endregion
diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h
index a0093501b561..e552d195fbf7 100644
--- a/src/coreclr/inc/corinfo.h
+++ b/src/coreclr/inc/corinfo.h
@@ -892,16 +892,6 @@ enum CorInfoIntrinsics
CORINFO_INTRINSIC_StubHelpers_GetStubContextAddr,
CORINFO_INTRINSIC_StubHelpers_NextCallReturnAddress,
- CORINFO_INTRINSIC_InterlockedAdd32,
- CORINFO_INTRINSIC_InterlockedAdd64,
- CORINFO_INTRINSIC_InterlockedXAdd32,
- CORINFO_INTRINSIC_InterlockedXAdd64,
- CORINFO_INTRINSIC_InterlockedXchg32,
- CORINFO_INTRINSIC_InterlockedXchg64,
- CORINFO_INTRINSIC_InterlockedCmpXchg32,
- CORINFO_INTRINSIC_InterlockedCmpXchg64,
- CORINFO_INTRINSIC_MemoryBarrier,
- CORINFO_INTRINSIC_MemoryBarrierLoad,
CORINFO_INTRINSIC_ByReference_Ctor,
CORINFO_INTRINSIC_ByReference_Value,
CORINFO_INTRINSIC_GetRawHandle,
diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h
index 092ac22313af..6aca52f5884e 100644
--- a/src/coreclr/inc/jiteeversionguid.h
+++ b/src/coreclr/inc/jiteeversionguid.h
@@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
#define GUID_DEFINED
#endif // !GUID_DEFINED
-constexpr GUID JITEEVersionIdentifier = { /* 4ef06a0e-e58d-4796-abb7-0cda6460610c */
- 0x4ef06a0e,
- 0xe58d,
- 0x4796,
- {0xab, 0xb7, 0xc, 0xda, 0x64, 0x60, 0x61, 0xc}
+constexpr GUID JITEEVersionIdentifier = { /* 802cceb2-2ebd-4ff9-ac31-4c3546a02aa5 */
+ 0x802cceb2,
+ 0x2ebd,
+ 0x4ff9,
+ {0xac, 0x31, 0x4c, 0x35, 0x46, 0xa0, 0x2a, 0xa5}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp
index f31f5df43098..5bfa06c31bad 100644
--- a/src/coreclr/jit/importer.cpp
+++ b/src/coreclr/jit/importer.cpp
@@ -3734,10 +3734,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
*pIntrinsicID = intrinsicID;
-#ifndef TARGET_ARM
- genTreeOps interlockedOperator;
-#endif
-
if (intrinsicID == CORINFO_INTRINSIC_StubHelpers_GetStubContext)
{
// must be done regardless of DbgCode and MinOpts
@@ -3785,96 +3781,6 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
{
GenTree* op1;
-#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
- // TODO-ARM-CQ: reenable treating Interlocked operation as intrinsic
-
- // Note that CORINFO_INTRINSIC_InterlockedAdd32/64 are not actually used.
- // Anyway, we can import them as XADD and leave it to lowering/codegen to perform
- // whatever optimizations may arise from the fact that result value is not used.
- case CORINFO_INTRINSIC_InterlockedAdd32:
- case CORINFO_INTRINSIC_InterlockedXAdd32:
- interlockedOperator = GT_XADD;
- goto InterlockedBinOpCommon;
- case CORINFO_INTRINSIC_InterlockedXchg32:
- interlockedOperator = GT_XCHG;
- goto InterlockedBinOpCommon;
-
-#ifdef TARGET_64BIT
- case CORINFO_INTRINSIC_InterlockedAdd64:
- case CORINFO_INTRINSIC_InterlockedXAdd64:
- interlockedOperator = GT_XADD;
- goto InterlockedBinOpCommon;
- case CORINFO_INTRINSIC_InterlockedXchg64:
- interlockedOperator = GT_XCHG;
- goto InterlockedBinOpCommon;
-#endif // TARGET_AMD64
-
- InterlockedBinOpCommon:
- assert(callType != TYP_STRUCT);
- assert(sig->numArgs == 2);
-
- GenTree* op2;
- op2 = impPopStack().val;
- op1 = impPopStack().val;
-
- // This creates:
- // val
- // XAdd
- // addr
- // field (for example)
- //
- // In the case where the first argument is the address of a local, we might
- // want to make this *not* make the var address-taken -- but atomic instructions
- // on a local are probably pretty useless anyway, so we probably don't care.
-
- op1 = gtNewOperNode(interlockedOperator, genActualType(callType), op1, op2);
- op1->gtFlags |= GTF_GLOB_REF | GTF_ASG;
- retNode = op1;
- break;
-#endif // defined(TARGET_XARCH) || defined(TARGET_ARM64)
-
- case CORINFO_INTRINSIC_MemoryBarrier:
- case CORINFO_INTRINSIC_MemoryBarrierLoad:
-
- assert(sig->numArgs == 0);
-
- op1 = new (this, GT_MEMORYBARRIER) GenTree(GT_MEMORYBARRIER, TYP_VOID);
- op1->gtFlags |= GTF_GLOB_REF | GTF_ASG;
-
- // On XARCH `CORINFO_INTRINSIC_MemoryBarrierLoad` fences need not be emitted.
- // However, we still need to capture the effect on reordering.
- if (intrinsicID == CORINFO_INTRINSIC_MemoryBarrierLoad)
- {
- op1->gtFlags |= GTF_MEMORYBARRIER_LOAD;
- }
-
- retNode = op1;
- break;
-
-#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
- // TODO-ARM-CQ: reenable treating InterlockedCmpXchg32 operation as intrinsic
- case CORINFO_INTRINSIC_InterlockedCmpXchg32:
-#ifdef TARGET_64BIT
- case CORINFO_INTRINSIC_InterlockedCmpXchg64:
-#endif
- {
- assert(callType != TYP_STRUCT);
- assert(sig->numArgs == 3);
- GenTree* op2;
- GenTree* op3;
-
- op3 = impPopStack().val; // comparand
- op2 = impPopStack().val; // value
- op1 = impPopStack().val; // location
-
- GenTree* node = new (this, GT_CMPXCHG) GenTreeCmpXchg(genActualType(callType), op1, op2, op3);
-
- node->AsCmpXchg()->gtOpLocation->gtFlags |= GTF_DONT_CSE;
- retNode = node;
- break;
- }
-#endif // defined(TARGET_XARCH) || defined(TARGET_ARM64)
-
case CORINFO_INTRINSIC_InitializeArray:
retNode = impInitializeArrayIntrinsic(sig);
break;
@@ -4372,6 +4278,90 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
}
#endif // TARGET_ARM64
+#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
+ // TODO-ARM-CQ: reenable treating InterlockedCmpXchg32 operation as intrinsic
+ case NI_System_Threading_Interlocked_CompareExchange:
+ {
+ var_types retType = JITtype2varType(sig->retType);
+ if ((retType == TYP_LONG) && (TARGET_POINTER_SIZE == 4))
+ {
+ break;
+ }
+ if ((retType != TYP_INT) && (retType != TYP_LONG))
+ {
+ break;
+ }
+
+ assert(callType != TYP_STRUCT);
+ assert(sig->numArgs == 3);
+
+ GenTree* op3 = impPopStack().val; // comparand
+ GenTree* op2 = impPopStack().val; // value
+ GenTree* op1 = impPopStack().val; // location
+
+ GenTree* node = new (this, GT_CMPXCHG) GenTreeCmpXchg(genActualType(callType), op1, op2, op3);
+
+ node->AsCmpXchg()->gtOpLocation->gtFlags |= GTF_DONT_CSE;
+ retNode = node;
+ break;
+ }
+
+ case NI_System_Threading_Interlocked_Exchange:
+ case NI_System_Threading_Interlocked_ExchangeAdd:
+ {
+ assert(callType != TYP_STRUCT);
+ assert(sig->numArgs == 2);
+
+ var_types retType = JITtype2varType(sig->retType);
+ if ((retType == TYP_LONG) && (TARGET_POINTER_SIZE == 4))
+ {
+ break;
+ }
+ if ((retType != TYP_INT) && (retType != TYP_LONG))
+ {
+ break;
+ }
+
+ GenTree* op2 = impPopStack().val;
+ GenTree* op1 = impPopStack().val;
+
+ // This creates:
+ // val
+ // XAdd
+ // addr
+ // field (for example)
+ //
+ // In the case where the first argument is the address of a local, we might
+ // want to make this *not* make the var address-taken -- but atomic instructions
+ // on a local are probably pretty useless anyway, so we probably don't care.
+
+ op1 = gtNewOperNode(ni == NI_System_Threading_Interlocked_ExchangeAdd ? GT_XADD : GT_XCHG,
+ genActualType(callType), op1, op2);
+ op1->gtFlags |= GTF_GLOB_REF | GTF_ASG;
+ retNode = op1;
+ break;
+ }
+#endif // defined(TARGET_XARCH) || defined(TARGET_ARM64)
+
+ case NI_System_Threading_Interlocked_MemoryBarrier:
+ case NI_System_Threading_Interlocked_ReadMemoryBarrier:
+ {
+ assert(sig->numArgs == 0);
+
+ GenTree* op1 = new (this, GT_MEMORYBARRIER) GenTree(GT_MEMORYBARRIER, TYP_VOID);
+ op1->gtFlags |= GTF_GLOB_REF | GTF_ASG;
+
+ // On XARCH `NI_System_Threading_Interlocked_ReadMemoryBarrier` fences need not be emitted.
+ // However, we still need to capture the effect on reordering.
+ if (ni == NI_System_Threading_Interlocked_ReadMemoryBarrier)
+ {
+ op1->gtFlags |= GTF_MEMORYBARRIER_LOAD;
+ }
+
+ retNode = op1;
+ break;
+ }
+
#ifdef FEATURE_HW_INTRINSICS
case NI_System_Math_FusedMultiplyAdd:
{
@@ -4962,10 +4952,10 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
result = NI_System_Threading_Thread_get_ManagedThreadId;
}
}
-#ifndef TARGET_ARM64
- // TODO-CQ: Implement for XArch (https://github.com/dotnet/runtime/issues/32239).
else if (strcmp(className, "Interlocked") == 0)
{
+#ifndef TARGET_ARM64
+ // TODO-CQ: Implement for XArch (https://github.com/dotnet/runtime/issues/32239).
if (strcmp(methodName, "And") == 0)
{
result = NI_System_Threading_Interlocked_And;
@@ -4974,8 +4964,28 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
{
result = NI_System_Threading_Interlocked_Or;
}
- }
#endif
+ if (strcmp(methodName, "CompareExchange") == 0)
+ {
+ result = NI_System_Threading_Interlocked_CompareExchange;
+ }
+ else if (strcmp(methodName, "Exchange") == 0)
+ {
+ result = NI_System_Threading_Interlocked_Exchange;
+ }
+ else if (strcmp(methodName, "ExchangeAdd") == 0)
+ {
+ result = NI_System_Threading_Interlocked_ExchangeAdd;
+ }
+ else if (strcmp(methodName, "MemoryBarrier") == 0)
+ {
+ result = NI_System_Threading_Interlocked_MemoryBarrier;
+ }
+ else if (strcmp(methodName, "ReadMemoryBarrier") == 0)
+ {
+ result = NI_System_Threading_Interlocked_ReadMemoryBarrier;
+ }
+ }
}
#if defined(TARGET_XARCH) || defined(TARGET_ARM64)
else if (strcmp(namespaceName, "System.Buffers.Binary") == 0)
diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h
index 8d162ab3421f..e972b4ad68cd 100644
--- a/src/coreclr/jit/namedintrinsiclist.h
+++ b/src/coreclr/jit/namedintrinsiclist.h
@@ -73,6 +73,11 @@ enum NamedIntrinsic : unsigned short
NI_System_Threading_Interlocked_And,
NI_System_Threading_Interlocked_Or,
+ NI_System_Threading_Interlocked_CompareExchange,
+ NI_System_Threading_Interlocked_Exchange,
+ NI_System_Threading_Interlocked_ExchangeAdd,
+ NI_System_Threading_Interlocked_MemoryBarrier,
+ NI_System_Threading_Interlocked_ReadMemoryBarrier,
#ifdef FEATURE_HW_INTRINSICS
NI_HW_INTRINSIC_START,
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs
index e55413b11186..ac2eb0668591 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.Intrinsics.cs
@@ -85,16 +85,6 @@ static IntrinsicHashtable InitializeIntrinsicHashtable()
table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_StubHelpers_GetStubContext, "GetStubContext", "System.StubHelpers", "StubHelpers"); // interop-specific
// table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_StubHelpers_GetStubContextAddr, "GetStubContextAddr", "System.StubHelpers", "StubHelpers"); // interop-specific
table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_StubHelpers_NextCallReturnAddress, "NextCallReturnAddress", "System.StubHelpers", "StubHelpers");
- // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedAdd32, "Add", System.Threading", "Interlocked"); // unused
- // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedAdd64, "Add", System.Threading", "Interlocked"); // unused
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXAdd32, "ExchangeAdd", "System.Threading", "Interlocked");
- // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXAdd64, "ExchangeAdd", "System.Threading", "Interlocked"); // ambiguous match
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXchg32, "Exchange", "System.Threading", "Interlocked");
- // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXchg64, "Exchange", "System.Threading", "Interlocked"); // ambiguous match
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg32, "CompareExchange", "System.Threading", "Interlocked");
- // table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg64, "CompareExchange", "System.Threading", "Interlocked"); // ambiguous match
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_MemoryBarrier, "MemoryBarrier", "System.Threading", "Interlocked");
- table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_MemoryBarrierLoad, "LoadBarrier", "System.Threading", "Interlocked");
table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_ByReference_Ctor, ".ctor", "System", "ByReference`1");
table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_ByReference_Value, "get_Value", "System", "ByReference`1");
table.Add(CorInfoIntrinsics.CORINFO_INTRINSIC_GetRawHandle, "EETypePtrOf", "System", "EETypePtr");
@@ -145,26 +135,6 @@ private CorInfoIntrinsics getIntrinsicID(MethodDesc method, byte* pMustExpand)
return CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal;
break;
- case CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXAdd32:
- case CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXchg32:
- case CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg32:
- {
- // RyuJIT handles int32 and int64 overloads only
- var returnTypeCategory = method.Signature.ReturnType.Category;
- if (returnTypeCategory != TypeFlags.Int32 && returnTypeCategory != TypeFlags.Int64 && returnTypeCategory != TypeFlags.IntPtr)
- return CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal;
-
- // int64 overloads have different ids
- if (returnTypeCategory == TypeFlags.Int64)
- {
- Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXAdd32 + 1 == (int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXAdd64);
- Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXchg32 + 1 == (int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedXchg64);
- Debug.Assert((int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg32 + 1 == (int)CorInfoIntrinsics.CORINFO_INTRINSIC_InterlockedCmpXchg64);
- id = (CorInfoIntrinsics)((int)id + 1);
- }
- }
- break;
-
case CorInfoIntrinsics.CORINFO_INTRINSIC_RTH_GetValueInternal:
#if !READYTORUN
case CorInfoIntrinsics.CORINFO_INTRINSIC_InitializeArray:
diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs
index 360ffc2ab635..087ab9a5c273 100644
--- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs
+++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs
@@ -448,16 +448,6 @@ public enum CorInfoIntrinsics
CORINFO_INTRINSIC_StubHelpers_GetStubContext,
CORINFO_INTRINSIC_StubHelpers_GetStubContextAddr,
CORINFO_INTRINSIC_StubHelpers_NextCallReturnAddress,
- CORINFO_INTRINSIC_InterlockedAdd32,
- CORINFO_INTRINSIC_InterlockedAdd64,
- CORINFO_INTRINSIC_InterlockedXAdd32,
- CORINFO_INTRINSIC_InterlockedXAdd64,
- CORINFO_INTRINSIC_InterlockedXchg32,
- CORINFO_INTRINSIC_InterlockedXchg64,
- CORINFO_INTRINSIC_InterlockedCmpXchg32,
- CORINFO_INTRINSIC_InterlockedCmpXchg64,
- CORINFO_INTRINSIC_MemoryBarrier,
- CORINFO_INTRINSIC_MemoryBarrierLoad,
CORINFO_INTRINSIC_ByReference_Ctor,
CORINFO_INTRINSIC_ByReference_Value,
CORINFO_INTRINSIC_GetRawHandle,
diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h
index b8bf08d5289f..a93343b112a4 100644
--- a/src/coreclr/vm/ecalllist.h
+++ b/src/coreclr/vm/ecalllist.h
@@ -803,21 +803,20 @@ FCFuncStart(gMissingMemberExceptionFuncs)
FCFuncEnd()
FCFuncStart(gInterlockedFuncs)
- FCIntrinsicSig("Exchange", &gsig_SM_RefInt_Int_RetInt, COMInterlocked::Exchange, CORINFO_INTRINSIC_InterlockedXchg32)
- FCIntrinsicSig("Exchange", &gsig_SM_RefLong_Long_RetLong, COMInterlocked::Exchange64, CORINFO_INTRINSIC_InterlockedXchg64)
+ FCFuncElementSig("Exchange", &gsig_SM_RefInt_Int_RetInt, COMInterlocked::Exchange)
+ FCFuncElementSig("Exchange", &gsig_SM_RefLong_Long_RetLong, COMInterlocked::Exchange64)
FCFuncElementSig("Exchange", &gsig_SM_RefDbl_Dbl_RetDbl, COMInterlocked::ExchangeDouble)
FCFuncElementSig("Exchange", &gsig_SM_RefFlt_Flt_RetFlt, COMInterlocked::ExchangeFloat)
FCFuncElementSig("Exchange", &gsig_SM_RefObj_Obj_RetObj, COMInterlocked::ExchangeObject)
- FCIntrinsicSig("CompareExchange", &gsig_SM_RefInt_Int_Int_RetInt, COMInterlocked::CompareExchange, CORINFO_INTRINSIC_InterlockedCmpXchg32)
- FCIntrinsicSig("CompareExchange", &gsig_SM_RefLong_Long_Long_RetLong, COMInterlocked::CompareExchange64, CORINFO_INTRINSIC_InterlockedCmpXchg64)
+ FCFuncElementSig("CompareExchange", &gsig_SM_RefInt_Int_Int_RetInt, COMInterlocked::CompareExchange)
+ FCFuncElementSig("CompareExchange", &gsig_SM_RefLong_Long_Long_RetLong, COMInterlocked::CompareExchange64)
FCFuncElementSig("CompareExchange", &gsig_SM_RefDbl_Dbl_Dbl_RetDbl, COMInterlocked::CompareExchangeDouble)
FCFuncElementSig("CompareExchange", &gsig_SM_RefFlt_Flt_Flt_RetFlt, COMInterlocked::CompareExchangeFloat)
FCFuncElementSig("CompareExchange", &gsig_SM_RefObj_Obj_Obj_RetObj, COMInterlocked::CompareExchangeObject)
- FCIntrinsicSig("ExchangeAdd", &gsig_SM_RefInt_Int_RetInt, COMInterlocked::ExchangeAdd32, CORINFO_INTRINSIC_InterlockedXAdd32)
- FCIntrinsicSig("ExchangeAdd", &gsig_SM_RefLong_Long_RetLong, COMInterlocked::ExchangeAdd64, CORINFO_INTRINSIC_InterlockedXAdd64)
-
- FCIntrinsic("MemoryBarrier", COMInterlocked::FCMemoryBarrier, CORINFO_INTRINSIC_MemoryBarrier)
- FCIntrinsic("ReadMemoryBarrier", COMInterlocked::FCMemoryBarrierLoad, CORINFO_INTRINSIC_MemoryBarrierLoad)
+ FCFuncElementSig("ExchangeAdd", &gsig_SM_RefInt_Int_RetInt, COMInterlocked::ExchangeAdd32)
+ FCFuncElementSig("ExchangeAdd", &gsig_SM_RefLong_Long_RetLong, COMInterlocked::ExchangeAdd64)
+ FCFuncElement("MemoryBarrier", COMInterlocked::FCMemoryBarrier)
+ FCFuncElement("ReadMemoryBarrier", COMInterlocked::FCMemoryBarrierLoad)
QCFuncElement("_MemoryBarrierProcessWide", COMInterlocked::MemoryBarrierProcessWide)
FCFuncEnd()