diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index d91c0feb383c4b..c2b3cdb808d879 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -3942,14 +3942,9 @@ void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& d case GenIntCastDesc::CHECK_INT_RANGE: { - const regNumber tempReg = cast->GetSingleTempReg(); - assert(tempReg != reg); - instGen_Set_Reg_To_Imm(EA_8BYTE, tempReg, INT32_MAX); - GetEmitter()->emitIns_R_R(INS_cmp, EA_8BYTE, reg, tempReg); - genJumpToThrowHlpBlk(EJ_gt, SCK_OVERFLOW); - instGen_Set_Reg_To_Imm(EA_8BYTE, tempReg, INT32_MIN); - GetEmitter()->emitIns_R_R(INS_cmp, EA_8BYTE, reg, tempReg); - genJumpToThrowHlpBlk(EJ_lt, SCK_OVERFLOW); + // Emit "if ((long)(int)x != x) goto OVERFLOW" + GetEmitter()->emitIns_R_R(INS_cmp, EA_8BYTE, reg, reg, INS_OPTS_SXTW); + genJumpToThrowHlpBlk(EJ_ne, SCK_OVERFLOW); } break; #endif diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index be96c95750cc2a..56b2ffddb38347 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -6648,11 +6648,14 @@ void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& d break; case GenIntCastDesc::CHECK_INT_RANGE: - GetEmitter()->emitIns_R_I(INS_cmp, EA_8BYTE, reg, INT32_MAX); - genJumpToThrowHlpBlk(EJ_jg, SCK_OVERFLOW); - GetEmitter()->emitIns_R_I(INS_cmp, EA_8BYTE, reg, INT32_MIN); - genJumpToThrowHlpBlk(EJ_jl, SCK_OVERFLOW); - break; + { + // Emit "if ((long)(int)x != x) goto OVERFLOW" + const regNumber regTmp = cast->GetSingleTempReg(); + GetEmitter()->emitIns_Mov(INS_movsxd, EA_8BYTE, regTmp, reg, true); + GetEmitter()->emitIns_R_R(INS_cmp, EA_8BYTE, reg, regTmp); + genJumpToThrowHlpBlk(EJ_jne, SCK_OVERFLOW); + } + break; #endif default: diff --git a/src/coreclr/jit/emitarm64.cpp b/src/coreclr/jit/emitarm64.cpp index 864ba862edddd7..ee03b7a7041e20 100644 --- a/src/coreclr/jit/emitarm64.cpp +++ b/src/coreclr/jit/emitarm64.cpp @@ -4503,14 +4503,16 @@ void emitter::emitIns_R_R( case INS_str: case INS_strb: case INS_strh: - - case INS_cmp: case INS_cmn: case INS_tst: assert(insOptsNone(opt)); emitIns_R_R_I(ins, attr, reg1, reg2, 0, INS_OPTS_NONE); return; + case INS_cmp: + emitIns_R_R_I(ins, attr, reg1, reg2, 0, opt); + return; + case INS_staddb: emitIns_R_R_R(INS_ldaddb, attr, reg1, REG_ZR, reg2); return; diff --git a/src/coreclr/jit/lsraarmarch.cpp b/src/coreclr/jit/lsraarmarch.cpp index 4a9eefef350c57..170cb38aa98bab 100644 --- a/src/coreclr/jit/lsraarmarch.cpp +++ b/src/coreclr/jit/lsraarmarch.cpp @@ -820,13 +820,6 @@ int LinearScan::BuildCast(GenTreeCast* cast) buildInternalFloatRegisterDefForNode(cast, RBM_ALLFLOAT); setInternalRegsDelayFree = true; } -#else - // Overflow checking cast from TYP_LONG to TYP_INT requires a temporary register to - // store the min and max immediate values that cannot be encoded in the CMP instruction. - if (cast->gtOverflow() && varTypeIsLong(srcType) && !cast->IsUnsigned() && (castType == TYP_INT)) - { - buildInternalIntRegisterDefForNode(cast); - } #endif int srcCount = BuildOperandUses(src); diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index 1e5f03463c8079..d0d74fa94cb06d 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -2480,9 +2480,9 @@ int LinearScan::BuildCast(GenTreeCast* cast) assert(!varTypeIsLong(srcType) || (src->OperIs(GT_LONG) && src->isContained())); #else - // Overflow checking cast from TYP_(U)LONG to TYP_UINT requires a temporary + // Overflow checking cast from TYP_(U)LONG to TYP_(U)INT requires a temporary // register to extract the upper 32 bits of the 64 bit source register. - if (cast->gtOverflow() && varTypeIsLong(srcType) && (castType == TYP_UINT)) + if (cast->gtOverflow() && varTypeIsLong(srcType) && varTypeIsInt(castType)) { // Here we don't need internal register to be different from targetReg, // rather require it to be different from operand's reg.