diff --git a/src/coreclr/jit/optcse.cpp b/src/coreclr/jit/optcse.cpp index b39b2bd1425c45..d17e3cba5e4d90 100644 --- a/src/coreclr/jit/optcse.cpp +++ b/src/coreclr/jit/optcse.cpp @@ -2598,17 +2598,18 @@ class CSE_Heuristic cse_use_cost *= slotCount; } - // If this CSE is live across a call then we may need to spill an additional caller save register + // If this CSE is live across a call then we may have additional costs // if (candidate->LiveAcrossCall()) { - if (candidate->Expr()->IsCnsFltOrDbl() && (CNT_CALLEE_SAVED_FLOAT == 0) && - (candidate->CseDsc()->csdUseWtCnt <= 4)) + // If we have a floating-point CSE that is both live across a call and there + // are no callee-saved FP registers available, the RA will have to spill at + // the def site and reload at the (first) use site, if the variable is a register + // candidate. Account for that. + if (varTypeIsFloating(candidate->Expr()) && (CNT_CALLEE_SAVED_FLOAT == 0) && !candidate->IsConservative()) { - // Floating point constants are expected to be contained, so unless there are more than 4 uses - // we better not to CSE them, especially on platforms without callee-saved registers - // for values living across calls - return false; + cse_def_cost += 1; + cse_use_cost += 1; } // If we don't have a lot of variables to enregister or we have a floating point type