Skip to content

Commit 454673e

Browse files
authored
JIT: fix case where importer can lose type information (#114033)
If the IL has branches with non-empty stack, the importer will spill the stack to temps. TYP_REF spill temps will never have any detailed type information. So if on the other side of the branch the IL immediately makes a call, the importer may direct sub the spill temp instead of creating a new arg temp that at least captures the declared argument type. This can (among other things) inhibit cloning based on loop-invariant delegate GDV. Partially addresses regressions in #113913.
1 parent 914ce6f commit 454673e

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

src/coreclr/jit/importer.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13651,6 +13651,20 @@ GenTree* Compiler::impInlineFetchArg(InlArgInfo& argInfo, const InlLclVarInfo& l
1365113651
GenTree* argNode = argInfo.arg->GetNode();
1365213652
assert(!argNode->OperIs(GT_RET_EXPR));
1365313653

13654+
// For TYP_REF args, if the argNode doesn't have any class information
13655+
// we will lose some type info if we directly substitute it.
13656+
// We can at least rely on the declared type of the arg here.
13657+
//
13658+
bool argLosesTypeInfo = false;
13659+
if (argNode->TypeIs(TYP_REF))
13660+
{
13661+
bool isExact;
13662+
bool isNeverNull;
13663+
CORINFO_CLASS_HANDLE argClass = gtGetClassHandle(argNode, &isExact, &isNeverNull);
13664+
13665+
argLosesTypeInfo = (argClass == NO_CLASS_HANDLE);
13666+
}
13667+
1365413668
if (argInfo.argIsInvariant && !argCanBeModified)
1365513669
{
1365613670
// Directly substitute constants or addresses of locals
@@ -13676,7 +13690,7 @@ GenTree* Compiler::impInlineFetchArg(InlArgInfo& argInfo, const InlLclVarInfo& l
1367613690
op1->gtType = genActualType(lclTyp);
1367713691
}
1367813692
}
13679-
else if (argInfo.argIsLclVar && !argCanBeModified && !argInfo.argHasCallerLocalRef)
13693+
else if (argInfo.argIsLclVar && !argCanBeModified && !argInfo.argHasCallerLocalRef && !argLosesTypeInfo)
1368013694
{
1368113695
// Directly substitute unaliased caller locals for args that cannot be modified
1368213696
//
@@ -13764,16 +13778,18 @@ GenTree* Compiler::impInlineFetchArg(InlArgInfo& argInfo, const InlLclVarInfo& l
1376413778
assert(lvaTable[tmpNum].lvSingleDef == 0);
1376513779
lvaTable[tmpNum].lvSingleDef = 1;
1376613780
JITDUMP("Marked V%02u as a single def temp\n", tmpNum);
13781+
1376713782
if (lclTyp == TYP_REF)
1376813783
{
13784+
// Use argNode type (when it exists) or lclInfo type
1376913785
lvaSetClass(tmpNum, argNode, lclInfo.lclTypeHandle);
1377013786
}
1377113787
}
1377213788
else
1377313789
{
1377413790
if (lclTyp == TYP_REF)
1377513791
{
13776-
// Arg might be modified, use the declared type of the argument.
13792+
// Arg might be modified. Use the declared type of the argument.
1377713793
lvaSetClass(tmpNum, lclInfo.lclTypeHandle);
1377813794
}
1377913795
}

0 commit comments

Comments
 (0)