diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index af168348e194d..fbea4ff5615ae 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -11258,13 +11258,31 @@ void LinearScan::RegisterSelection::try_SPILL_COST() continue; } - float currentSpillWeight = linearScan->spillCost[spillCandidateRegNum]; -#ifdef TARGET_ARM - if (currentInterval->registerType == TYP_DOUBLE) + float currentSpillWeight = 0; + RefPosition* recentRefPosition = spillCandidateRegRecord->assignedInterval->recentRefPosition; + if ((recentRefPosition != nullptr) && (recentRefPosition->RegOptional()) && + !(currentInterval->isLocalVar && recentRefPosition->IsActualRef())) { - currentSpillWeight = max(currentSpillWeight, linearScan->spillCost[REG_NEXT(spillCandidateRegNum)]); + // We do not "spillAfter" if previous (recent) refPosition was regOptional or if it + // is not an actual ref. In those cases, we will reload in future (next) refPosition. + // For such cases, consider the spill cost of next refposition. + RefPosition* reloadRefPosition = spillCandidateRegRecord->assignedInterval->getNextRefPosition(); + if (reloadRefPosition != nullptr) + { + currentSpillWeight = linearScan->getWeight(reloadRefPosition); + } } + else + { + currentSpillWeight = linearScan->spillCost[spillCandidateRegNum]; +#ifdef TARGET_ARM + if (currentInterval->registerType == TYP_DOUBLE) + { + currentSpillWeight = max(currentSpillWeight, linearScan->spillCost[REG_NEXT(spillCandidateRegNum)]); + } #endif + } + if (currentSpillWeight < bestSpillWeight) { bestSpillWeight = currentSpillWeight;