diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 81b40d5da6e114..8503a56605b292 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -567,8 +567,43 @@ void InterpCompiler::EmitBBEndVarMoves(InterpBasicBlock *pTargetBB) int dVar = pTargetBB->pStackState[i].var; if (sVar != dVar) { - InterpType interpType = m_pVars[sVar].interpType; - int32_t movOp = InterpGetMovForType(interpType, false); + InterpType interpType = g_interpTypeFromStackType[m_pStackBase[i].GetStackType()]; + InterpType interpDestType = g_interpTypeFromStackType[pTargetBB->pStackState[i].GetStackType()]; + int32_t movOp; + if (interpType != interpDestType) + { + if (interpType == InterpTypeR4 && interpDestType == InterpTypeR8) + { + movOp = INTOP_CONV_R8_R4; + } + else if (interpType == InterpTypeR8 && interpDestType == InterpTypeR4) + { + movOp = INTOP_CONV_R4_R8; + } + else if (interpType == InterpTypeI && interpDestType == InterpTypeByRef) + { + movOp = InterpGetMovForType(interpDestType, false); + } +#ifdef TARGET_64BIT + // nint and int32 can be used interchangeably. Add implicit conversions. + else if (interpType == InterpTypeI4 && interpDestType == InterpTypeI8) + { + movOp = INTOP_CONV_I8_I4; + } + else if (interpType == InterpTypeI8 && interpDestType == InterpTypeI4) + { + movOp = InterpGetMovForType(interpDestType, false); + } +#endif // TARGET_64BIT + else + { + BADCODE("Incompatible types on stack between basic blocks"); + } + } + else + { + movOp = InterpGetMovForType(interpType, false); + } AddIns(movOp); m_pLastNewIns->SetSVar(sVar); @@ -7945,6 +7980,26 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) if (m_compHnd->isValueClass(resolvedToken.hClass)) { + CorInfoType asCorInfoType = m_compHnd->asCorInfoType(m_compHnd->getTypeForBox(resolvedToken.hClass)); + if (asCorInfoType == CORINFO_TYPE_FLOAT && m_pStackPointer[-1].GetStackType() == StackTypeR8) + { + EmitConv(m_pStackPointer - 1, StackTypeR4, INTOP_CONV_R4_R8); + } + else if (asCorInfoType == CORINFO_TYPE_DOUBLE && m_pStackPointer[-1].GetStackType() == StackTypeR4) + { + EmitConv(m_pStackPointer - 1, StackTypeR8, INTOP_CONV_R8_R4); + } +#ifdef TARGET_64BIT + // nint and int32 can be used interchangeably. Add implicit conversions. + else if (asCorInfoType == CORINFO_TYPE_NATIVEINT && m_pStackPointer[-1].GetStackType() == StackTypeI4) + { + EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_I8_I4); + } + else if (asCorInfoType == CORINFO_TYPE_NATIVEUINT && m_pStackPointer[-1].GetStackType() == StackTypeI4) + { + EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_I8_U4); + } +#endif // TARGET_64BIT CORINFO_GENERICHANDLE_RESULT embedInfo; m_compHnd->embedGenericHandle(&resolvedToken, false, m_methodInfo->ftn, &embedInfo); m_pStackPointer -= 1;