Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b2401b5

Browse files
committed
Update lookupNamedIntrinsic to handle System.Runtime.Intrinsics for unsupported platforms
1 parent 5ec1fcd commit b2401b5

File tree

5 files changed

+88
-63
lines changed

5 files changed

+88
-63
lines changed

src/coreclr/src/jit/compiler.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3714,17 +3714,17 @@ class Compiler
37143714
CorInfoIntrinsics intrinsicID,
37153715
bool tailCall);
37163716
NamedIntrinsic lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method);
3717+
GenTree* impUnsupportedNamedIntrinsic(unsigned helper,
3718+
CORINFO_METHOD_HANDLE method,
3719+
CORINFO_SIG_INFO* sig,
3720+
bool mustExpand);
37173721

37183722
#ifdef FEATURE_HW_INTRINSICS
37193723
GenTree* impHWIntrinsic(NamedIntrinsic intrinsic,
37203724
CORINFO_CLASS_HANDLE clsHnd,
37213725
CORINFO_METHOD_HANDLE method,
37223726
CORINFO_SIG_INFO* sig,
37233727
bool mustExpand);
3724-
GenTree* impUnsupportedHWIntrinsic(unsigned helper,
3725-
CORINFO_METHOD_HANDLE method,
3726-
CORINFO_SIG_INFO* sig,
3727-
bool mustExpand);
37283728
GenTree* impSimdAsHWIntrinsic(NamedIntrinsic intrinsic,
37293729
CORINFO_CLASS_HANDLE clsHnd,
37303730
CORINFO_METHOD_HANDLE method,

src/coreclr/src/jit/emitarm64.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7561,6 +7561,7 @@ void emitter::emitIns_R_C(
75617561
assert(isValidGeneralDatasize(size));
75627562
}
75637563
break;
7564+
75647565
default:
75657566
unreached();
75667567
}

src/coreclr/src/jit/hwintrinsic.cpp

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -89,50 +89,6 @@ var_types Compiler::getBaseTypeFromArgIfNeeded(NamedIntrinsic intrinsic,
8989
return baseType;
9090
}
9191

92-
//------------------------------------------------------------------------
93-
// impUnsupportedHWIntrinsic: returns a node for an unsupported HWIntrinsic
94-
//
95-
// Arguments:
96-
// helper - JIT helper ID for the exception to be thrown
97-
// method - method handle of the intrinsic function.
98-
// sig - signature of the intrinsic call
99-
// mustExpand - true if the intrinsic must return a GenTree*; otherwise, false
100-
//
101-
// Return Value:
102-
// a gtNewMustThrowException if mustExpand is true; otherwise, nullptr
103-
//
104-
GenTree* Compiler::impUnsupportedHWIntrinsic(unsigned helper,
105-
CORINFO_METHOD_HANDLE method,
106-
CORINFO_SIG_INFO* sig,
107-
bool mustExpand)
108-
{
109-
// We've hit some error case and may need to return a node for the given error.
110-
//
111-
// When `mustExpand=false`, we are attempting to inline the intrinsic directly into another method. In this
112-
// scenario, we need to return `nullptr` so that a GT_CALL to the intrinsic is emitted instead. This is to
113-
// ensure that everything continues to behave correctly when optimizations are enabled (e.g. things like the
114-
// inliner may expect the node we return to have a certain signature, and the `MustThrowException` node won't
115-
// match that).
116-
//
117-
// When `mustExpand=true`, we are in a GT_CALL to the intrinsic and are attempting to JIT it. This will generally
118-
// be in response to an indirect call (e.g. done via reflection) or in response to an earlier attempt returning
119-
// `nullptr` (under `mustExpand=false`). In that scenario, we are safe to return the `MustThrowException` node.
120-
121-
if (mustExpand)
122-
{
123-
for (unsigned i = 0; i < sig->numArgs; i++)
124-
{
125-
impPopStack();
126-
}
127-
128-
return gtNewMustThrowException(helper, JITtype2varType(sig->retType), sig->retTypeClass);
129-
}
130-
else
131-
{
132-
return nullptr;
133-
}
134-
}
135-
13692
CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleForHWSIMD(var_types simdType, var_types simdBaseType)
13793
{
13894
if (simdType == TYP_SIMD16)

src/coreclr/src/jit/importer.cpp

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3478,29 +3478,34 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
34783478
{
34793479
ni = lookupNamedIntrinsic(method);
34803480

3481-
#ifdef FEATURE_HW_INTRINSICS
3481+
// We specially support the following on all platforms to allow for dead
3482+
// code optimization and to more generally support recursive intrinsics.
3483+
34823484
if (ni == NI_IsSupported_True)
34833485
{
3486+
assert(sig->numArgs == 0);
34843487
return gtNewIconNode(true);
34853488
}
34863489

34873490
if (ni == NI_IsSupported_False)
34883491
{
3492+
assert(sig->numArgs == 0);
34893493
return gtNewIconNode(false);
34903494
}
34913495

34923496
if (ni == NI_Throw_PlatformNotSupportedException)
34933497
{
3494-
return impUnsupportedHWIntrinsic(CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, method, sig, mustExpand);
3498+
return impUnsupportedNamedIntrinsic(CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, method, sig, mustExpand);
34953499
}
34963500

3501+
#ifdef FEATURE_HW_INTRINSICS
34973502
if ((ni > NI_HW_INTRINSIC_START) && (ni < NI_HW_INTRINSIC_END))
34983503
{
34993504
GenTree* hwintrinsic = impHWIntrinsic(ni, clsHnd, method, sig, mustExpand);
35003505

35013506
if (mustExpand && (hwintrinsic == nullptr))
35023507
{
3503-
return impUnsupportedHWIntrinsic(CORINFO_HELP_THROW_NOT_IMPLEMENTED, method, sig, mustExpand);
3508+
return impUnsupportedNamedIntrinsic(CORINFO_HELP_THROW_NOT_IMPLEMENTED, method, sig, mustExpand);
35043509
}
35053510

35063511
return hwintrinsic;
@@ -4273,14 +4278,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis,
42734278
if (mustExpand && (retNode == nullptr))
42744279
{
42754280
assert(!"Unhandled must expand intrinsic, throwing PlatformNotSupportedException");
4276-
4277-
for (unsigned i = 0; i < sig->numArgs; i++)
4278-
{
4279-
impPopStack();
4280-
}
4281-
4282-
return gtNewMustThrowException(CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, JITtype2varType(sig->retType),
4283-
sig->retTypeClass);
4281+
return impUnsupportedNamedIntrinsic(CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, method, sig, mustExpand);
42844282
}
42854283

42864284
// Optionally report if this intrinsic is special
@@ -4497,8 +4495,13 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
44974495

44984496
result = SimdAsHWIntrinsicInfo::lookupId(&sig, className, methodName, enclosingClassName, sizeOfVectorT);
44994497
}
4498+
#endif // FEATURE_HW_INTRINSICS
45004499
else if (strncmp(namespaceName, "System.Runtime.Intrinsics", 25) == 0)
45014500
{
4501+
// We go down this path even when FEATURE_HW_INTRINSICS isn't enabled
4502+
// so we can specially handle IsSupported and recursive calls.
4503+
4504+
#ifdef FEATURE_HW_INTRINSICS
45024505
namespaceName += 25;
45034506
const char* platformNamespaceName;
45044507

@@ -4517,29 +4520,91 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method)
45174520

45184521
result = HWIntrinsicInfo::lookupId(this, &sig, className, methodName, enclosingClassName);
45194522
}
4523+
#endif // FEATURE_HW_INTRINSICS
45204524

45214525
if (result == NI_Illegal)
45224526
{
45234527
if (strcmp(methodName, "get_IsSupported") == 0)
45244528
{
4525-
return NI_IsSupported_False;
4529+
// This allows the relevant code paths to be dropped as dead code even
4530+
// on platforms where FEATURE_HW_INTRINSICS is not supported.
4531+
4532+
result = NI_IsSupported_False;
4533+
}
4534+
else if (gtIsRecursiveCall(method))
4535+
{
4536+
// For the framework itself, any recursive intrinsics will either be
4537+
// only supported on a single platform or will be guarded by a relevant
4538+
// IsSupported check so the throw PNSE will be valid or dropped.
4539+
4540+
result = NI_Throw_PlatformNotSupportedException;
45264541
}
4527-
return gtIsRecursiveCall(method) ? NI_Throw_PlatformNotSupportedException : NI_Illegal;
45284542
}
45294543
}
4530-
#endif // FEATURE_HW_INTRINSICS
45314544

45324545
if (result == NI_Illegal)
45334546
{
45344547
JITDUMP("Not recognized\n");
45354548
}
4549+
else if (result == NI_IsSupported_False)
4550+
{
4551+
JITDUMP("Unsupported - return false");
4552+
}
4553+
else if (result == NI_Throw_PlatformNotSupportedException)
4554+
{
4555+
JITDUMP("Unsupported - throw PlatformNotSupportedException");
4556+
}
45364557
else
45374558
{
45384559
JITDUMP("Recognized\n");
45394560
}
45404561
return result;
45414562
}
45424563

4564+
//------------------------------------------------------------------------
4565+
// impUnsupportedNamedIntrinsic: Throws an exception for an unsupported named intrinsic
4566+
//
4567+
// Arguments:
4568+
// helper - JIT helper ID for the exception to be thrown
4569+
// method - method handle of the intrinsic function.
4570+
// sig - signature of the intrinsic call
4571+
// mustExpand - true if the intrinsic must return a GenTree*; otherwise, false
4572+
//
4573+
// Return Value:
4574+
// a gtNewMustThrowException if mustExpand is true; otherwise, nullptr
4575+
//
4576+
GenTree* Compiler::impUnsupportedNamedIntrinsic(unsigned helper,
4577+
CORINFO_METHOD_HANDLE method,
4578+
CORINFO_SIG_INFO* sig,
4579+
bool mustExpand)
4580+
{
4581+
// We've hit some error case and may need to return a node for the given error.
4582+
//
4583+
// When `mustExpand=false`, we are attempting to inline the intrinsic directly into another method. In this
4584+
// scenario, we need to return `nullptr` so that a GT_CALL to the intrinsic is emitted instead. This is to
4585+
// ensure that everything continues to behave correctly when optimizations are enabled (e.g. things like the
4586+
// inliner may expect the node we return to have a certain signature, and the `MustThrowException` node won't
4587+
// match that).
4588+
//
4589+
// When `mustExpand=true`, we are in a GT_CALL to the intrinsic and are attempting to JIT it. This will generally
4590+
// be in response to an indirect call (e.g. done via reflection) or in response to an earlier attempt returning
4591+
// `nullptr` (under `mustExpand=false`). In that scenario, we are safe to return the `MustThrowException` node.
4592+
4593+
if (mustExpand)
4594+
{
4595+
for (unsigned i = 0; i < sig->numArgs; i++)
4596+
{
4597+
impPopStack();
4598+
}
4599+
4600+
return gtNewMustThrowException(helper, JITtype2varType(sig->retType), sig->retTypeClass);
4601+
}
4602+
else
4603+
{
4604+
return nullptr;
4605+
}
4606+
}
4607+
45434608
/*****************************************************************************/
45444609

45454610
GenTree* Compiler::impArrayAccessIntrinsic(

src/coreclr/src/jit/namedintrinsiclist.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@ enum NamedIntrinsic : unsigned short
2222
NI_System_Type_get_IsValueType,
2323
NI_System_Type_IsAssignableFrom,
2424

25-
#ifdef FEATURE_HW_INTRINSICS
25+
// These are used by HWIntrinsics but are defined more generally
26+
// to allow dead code optimization and handle the recursion case
27+
2628
NI_IsSupported_True,
2729
NI_IsSupported_False,
2830
NI_Throw_PlatformNotSupportedException,
2931

32+
#ifdef FEATURE_HW_INTRINSICS
3033
NI_HW_INTRINSIC_START,
3134
#if defined(TARGET_XARCH)
3235
#define HARDWARE_INTRINSIC(isa, name, size, numarg, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, category, flag) \

0 commit comments

Comments
 (0)