Skip to content

Commit

Permalink
Use signed types and skip intrinsifying floating-point
Browse files Browse the repository at this point in the history
  • Loading branch information
stephentoub committed Jul 17, 2024
1 parent 4a83109 commit 116f650
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ public static MethodIL EmitIL(
{
ceArgType = method.Context.GetWellKnownType(WellKnownType.Object);
}
else if (tType.IsPrimitive || tType.IsEnum)
else if ((tType.IsPrimitive || tType.IsEnum) && (tType.UnderlyingType.Category is not (TypeFlags.Single or TypeFlags.Double)))
{
int size = tType.GetElementSize().AsInt;
Debug.Assert(size is 1 or 2 or 4 or 8);
ceArgType = size switch
{
1 => method.Context.GetWellKnownType(WellKnownType.Byte),
2 => method.Context.GetWellKnownType(WellKnownType.UInt16),
4 => method.Context.GetWellKnownType(WellKnownType.UInt32),
_ => method.Context.GetWellKnownType(WellKnownType.UInt64),
4 => method.Context.GetWellKnownType(WellKnownType.Int32),
_ => method.Context.GetWellKnownType(WellKnownType.Int64),
};
}

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/vm/corelib.h
Original file line number Diff line number Diff line change
Expand Up @@ -696,8 +696,8 @@ DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_T, CompareExchange, GM_
DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_OBJECT,CompareExchange, SM_RefObject_Object_Object_RetObject)
DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_BYTE, CompareExchange, SM_RefByte_Byte_Byte_RetByte)
DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_USHRT, CompareExchange, SM_RefUShrt_UShrt_UShrt_RetUShrt)
DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_UINT, CompareExchange, SM_RefUInt_UInt_UInt_RetUInt)
DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_ULONG, CompareExchange, SM_RefULong_ULong_ULong_RetULong)
DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_INT, CompareExchange, SM_RefInt_Int_Int_RetInt)
DEFINE_METHOD(INTERLOCKED, COMPARE_EXCHANGE_LONG, CompareExchange, SM_RefLong_Long_Long_RetLong)

DEFINE_CLASS(RAW_DATA, CompilerServices, RawData)
DEFINE_FIELD(RAW_DATA, DATA, Data)
Expand Down
58 changes: 32 additions & 26 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7250,8 +7250,8 @@ bool getILIntrinsicImplementationForInterlocked(MethodDesc * ftn,
{ CEE_LDARG_0, CEE_LDARG_1, CEE_LDARG_2, CEE_CALL, 0, 0, 0, 0, CEE_RET }, // object
{ CEE_LDARG_0, CEE_LDARG_1, CEE_LDARG_2, CEE_CALL, 0, 0, 0, 0, CEE_RET }, // byte
{ CEE_LDARG_0, CEE_LDARG_1, CEE_LDARG_2, CEE_CALL, 0, 0, 0, 0, CEE_RET }, // ushort
{ CEE_LDARG_0, CEE_LDARG_1, CEE_LDARG_2, CEE_CALL, 0, 0, 0, 0, CEE_RET }, // uint
{ CEE_LDARG_0, CEE_LDARG_1, CEE_LDARG_2, CEE_CALL, 0, 0, 0, 0, CEE_RET }, // ulong
{ CEE_LDARG_0, CEE_LDARG_1, CEE_LDARG_2, CEE_CALL, 0, 0, 0, 0, CEE_RET }, // int
{ CEE_LDARG_0, CEE_LDARG_1, CEE_LDARG_2, CEE_CALL, 0, 0, 0, 0, CEE_RET }, // long
};

// Based on the generic method parameter, determine which overload of CompareExchange
Expand All @@ -7263,37 +7263,43 @@ bool getILIntrinsicImplementationForInterlocked(MethodDesc * ftn,
ilIndex = 0;
cmpxchgMethod = CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_OBJECT);
}
else if (!CorTypeInfo::IsPrimitiveType(typeHandle.GetVerifierCorElementType()))
{
return false;
}
else
{
switch (typeHandle.GetSize())
CorElementType elementType = typeHandle.GetVerifierCorElementType();
if (!CorTypeInfo::IsPrimitiveType(elementType) ||
elementType == ELEMENT_TYPE_R4 ||
elementType == ELEMENT_TYPE_R8)
{
case 1:
ilIndex = 1;
cmpxchgMethod = CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_BYTE);
break;
return false;
}
else
{
switch (typeHandle.GetSize())
{
case 1:
ilIndex = 1;
cmpxchgMethod = CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_BYTE);
break;

case 2:
ilIndex = 2;
cmpxchgMethod = CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_USHRT);
break;
case 2:
ilIndex = 2;
cmpxchgMethod = CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_USHRT);
break;

case 4:
ilIndex = 3;
cmpxchgMethod = CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_UINT);
break;
case 4:
ilIndex = 3;
cmpxchgMethod = CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_INT);
break;

case 8:
ilIndex = 4;
cmpxchgMethod = CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_ULONG);
break;
case 8:
ilIndex = 4;
cmpxchgMethod = CoreLibBinder::GetMethod(METHOD__INTERLOCKED__COMPARE_EXCHANGE_LONG);
break;

default:
_ASSERT(!"Unexpected primitive type size");
return false;
default:
_ASSERT(!"Unexpected primitive type size");
return false;
}
}
}

Expand Down
2 changes: 0 additions & 2 deletions src/coreclr/vm/metasig.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,8 +588,6 @@ DEFINE_METASIG(GM(RefT_T_T_RetT, IMAGE_CEE_CS_CALLCONV_DEFAULT, 1, r(M(0)) M(0)
DEFINE_METASIG(SM(RefObject_Object_Object_RetObject, r(j) j j, j))
DEFINE_METASIG(SM(RefByte_Byte_Byte_RetByte, r(b) b b, b))
DEFINE_METASIG(SM(RefUShrt_UShrt_UShrt_RetUShrt, r(H) H H, H))
DEFINE_METASIG(SM(RefUInt_UInt_UInt_RetUInt, r(K) K K, K))
DEFINE_METASIG(SM(RefULong_ULong_ULong_RetULong, r(L) L L, L))

DEFINE_METASIG_T(SM(RefCleanupWorkListElement_RetVoid, r(C(CLEANUP_WORK_LIST_ELEMENT)), v))
DEFINE_METASIG_T(SM(RefCleanupWorkListElement_SafeHandle_RetIntPtr, r(C(CLEANUP_WORK_LIST_ELEMENT)) C(SAFE_HANDLE), I))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,17 +274,17 @@ ref Unsafe.As<T, ushort>(ref location1),

if (sizeof(T) == 4)
{
return Unsafe.BitCast<uint, T>(
return Unsafe.BitCast<int, T>(
Exchange(
ref Unsafe.As<T, uint>(ref location1),
Unsafe.BitCast<T, uint>(value)));
ref Unsafe.As<T, int>(ref location1),
Unsafe.BitCast<T, int>(value)));
}

Debug.Assert(sizeof(T) == 8);
return Unsafe.BitCast<ulong, T>(
return Unsafe.BitCast<long, T>(
Exchange(
ref Unsafe.As<T, ulong>(ref location1),
Unsafe.BitCast<T, ulong>(value)));
ref Unsafe.As<T, long>(ref location1),
Unsafe.BitCast<T, long>(value)));
}
#endregion

Expand Down Expand Up @@ -528,19 +528,19 @@ ref Unsafe.As<T, ushort>(ref location1),

if (sizeof(T) == 4)
{
return Unsafe.BitCast<uint, T>(
return Unsafe.BitCast<int, T>(
CompareExchange(
ref Unsafe.As<T, uint>(ref location1),
Unsafe.BitCast<T, uint>(value),
Unsafe.BitCast<T, uint>(comparand)));
ref Unsafe.As<T, int>(ref location1),
Unsafe.BitCast<T, int>(value),
Unsafe.BitCast<T, int>(comparand)));
}

Debug.Assert(sizeof(T) == 8);
return Unsafe.BitCast<ulong, T>(
return Unsafe.BitCast<long, T>(
CompareExchange(
ref Unsafe.As<T, ulong>(ref location1),
Unsafe.BitCast<T, ulong>(value),
Unsafe.BitCast<T, ulong>(comparand)));
ref Unsafe.As<T, long>(ref location1),
Unsafe.BitCast<T, long>(value),
Unsafe.BitCast<T, long>(comparand)));
}
#endregion

Expand Down

0 comments on commit 116f650

Please sign in to comment.