Skip to content

Commit 9ca8b9e

Browse files
Masking away eGPR from GCREf nodes
1 parent 376aab0 commit 9ca8b9e

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

src/coreclr/jit/lsrabuild.cpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2835,6 +2835,22 @@ void LinearScan::buildInitialParamDef(const LclVarDsc* varDsc, regNumber paramRe
28352835
Interval* interval = getIntervalForLocalVar(varDsc->lvVarIndex);
28362836
const var_types regType = varDsc->GetRegisterType();
28372837
SingleTypeRegSet mask = allRegs(regType);
2838+
#ifdef TARGET_AMD64
2839+
if (varTypeIsGC(regType))
2840+
{
2841+
#ifdef DEBUG
2842+
if (VERBOSE)
2843+
{
2844+
printf("\n\n buildInitialParamDef : \n");
2845+
2846+
//compiler->gtDispTree(tree, nullptr, nullptr, true);
2847+
printf("(GC type)\n\n");
2848+
}
2849+
#endif // DEBUG
2850+
assert((mask & lowGprRegs) != RBM_NONE);
2851+
mask &= lowGprRegs;
2852+
}
2853+
#endif // TARGET_AMD64
28382854
if ((paramReg != REG_NA) && !stressInitialParamReg())
28392855
{
28402856
// Set this interval as currently assigned to that register
@@ -3079,6 +3095,30 @@ RefPosition* LinearScan::BuildDef(GenTree* tree, SingleTypeRegSet dstCandidates,
30793095
interval->hasInterferingUses = true;
30803096
// pendingDelayFree = false;
30813097
}
3098+
#ifdef TARGET_AMD64
3099+
if (varTypeIsGC(tree->TypeGet()))
3100+
{
3101+
#ifdef DEBUG
3102+
if (VERBOSE)
3103+
{
3104+
printf("\n\n BuildDef: tree : \n");
3105+
3106+
compiler->gtDispTree(tree, nullptr, nullptr, true);
3107+
printf("(GC type)\n\n");
3108+
}
3109+
#endif // DEBUG
3110+
if (dstCandidates == RBM_NONE)
3111+
{
3112+
dstCandidates = lowGprRegs;
3113+
}
3114+
else
3115+
{
3116+
// If we have a candidate register, it must be a low GPR.
3117+
assert((dstCandidates & lowGprRegs) != RBM_NONE);
3118+
dstCandidates &= lowGprRegs;
3119+
}
3120+
}
3121+
#endif // TARGET_AMD64
30823122
RefPosition* defRefPosition =
30833123
newRefPosition(interval, currentLoc + 1, RefTypeDef, tree, dstCandidates, multiRegIdx);
30843124
if (tree->IsUnusedValue())
@@ -4016,9 +4056,26 @@ void LinearScan::BuildStoreLocDef(GenTreeLclVarCommon* storeLoc,
40164056
{
40174057
defCandidates = allRegs(type);
40184058
}
4059+
#elif TARGET_AMD64
4060+
defCandidates = allRegs(type);
4061+
//if (varTypeIsGC(type))
4062+
if (varTypeUsesIntReg(type))
4063+
{
4064+
#ifdef DEBUG
4065+
if (VERBOSE)
4066+
{
4067+
printf("\n\n BuildStoreLocDef : \n");
4068+
4069+
//compiler->gtDispTree(tree, nullptr, nullptr, true);
4070+
printf("(GC type)\n\n");
4071+
}
4072+
#endif // DEBUG
4073+
assert((defCandidates & lowGprRegs) != RBM_NONE);
4074+
defCandidates &= lowGprRegs;
4075+
}
40194076
#else
40204077
defCandidates = allRegs(type);
4021-
#endif // TARGET_X86
4078+
#endif
40224079

40234080
RefPosition* def = newRefPosition(varDefInterval, currentLoc + 1, RefTypeDef, storeLoc, defCandidates, index);
40244081
if (varDefInterval->isWriteThru)

src/coreclr/jit/lsraxarch.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,10 +299,33 @@ int LinearScan::BuildNode(GenTree* tree)
299299
case GT_AND:
300300
case GT_OR:
301301
case GT_XOR:
302+
{
302303
srcCount = BuildBinaryUses(tree->AsOp());
303304
assert(dstCount == 1);
305+
#ifdef TARGET_AMD64
306+
GenTree* op1 = tree->AsOp()->gtGetOp1();
307+
GenTree* op2 = tree->AsOp()->gtGetOp2IfPresent();
308+
if ((op1 != nullptr) && (varTypeIsGC(op1->TypeGet()))
309+
|| (op2 != nullptr) && (varTypeIsGC(op2->TypeGet())))
310+
{
311+
// If either operand is a GC type, we need to use a low GPR.
312+
#ifdef DEBUG
313+
if (VERBOSE)
314+
{
315+
printf("\n\n BuildBinary: tree : \n");
316+
317+
compiler->gtDispTree(tree, nullptr, nullptr, true);
318+
printf("(GC type)\n\n");
319+
}
320+
#endif // DEBUG
321+
// For GC types, we always use a low GPR.
322+
BuildDef(tree, lowGprRegs);
323+
break;
324+
}
325+
#endif // TARGET_AMD64
304326
BuildDef(tree);
305327
break;
328+
}
306329

307330
case GT_RETURNTRAP:
308331
{
@@ -3109,7 +3132,11 @@ int LinearScan::BuildIndir(GenTreeIndir* indirTree)
31093132
#endif // FEATURE_SIMD
31103133

31113134
#ifdef TARGET_AMD64
3112-
if (varTypeUsesIntReg(indirTree->Addr()))
3135+
if (/*indirTree->OperIs(GT_STOREIND) && */varTypeIsGC(indirTree->Addr()->TypeGet()))
3136+
{
3137+
useCandidates = lowGprRegs; // StoreIndir with GC type address must use low GPRs
3138+
}
3139+
else if (varTypeUsesIntReg(indirTree->Addr()))
31133140
{
31143141
useCandidates = ForceLowGprForApxIfNeeded(indirTree->Addr(), useCandidates, getEvexIsSupported());
31153142
}

0 commit comments

Comments
 (0)