diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 4a0f707e605b30..6bca839d10514b 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -5943,6 +5943,27 @@ void CodeGen::genCompareInt(GenTree* treeNode) } else if (op1->isUsedFromReg() && op2->IsIntegralConst(0)) { + emitAttr targetSize = emitActualTypeSize(op1->TypeGet()); + emitAttr op1Size = emitActualTypeSize(op1->TypeGet()); + + // Optimize "x<0" and "x>=0" to "x>>31" if "x" is not a jump condition and in a reg. + // Morph/Lowering are responsible to rotate "00" so we won't handle it here. + if ((targetSize >= 4) && (op1Size >= 4) && (targetReg != REG_NA) && tree->OperIs(GT_LT, GT_GE)) + { + if (targetReg != op1->GetRegNum()) + { + inst_RV_RV(INS_mov, targetReg, op1->GetRegNum(), op1->TypeGet()); + } + if (tree->OperIs(GT_GE)) + { + // emit "not" for "x>=0" case + inst_RV(INS_not, targetReg, tree->TypeGet(), op1Size); + } + inst_RV_IV(INS_shr_N, targetReg, (int)op1Size * 8 - 1, op1Size); + genProduceReg(tree); + return; + } + if (compiler->opts.OptimizationEnabled()) { canReuseFlags = true;