diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 9172a30575779..1a32649e1e772 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3983,7 +3983,7 @@ class Compiler static void impBashVarAddrsToI(GenTree* tree1, GenTree* tree2 = nullptr); - GenTree* impImplicitIorI4Cast(GenTree* tree, var_types dstTyp); + GenTree* impImplicitIorI4Cast(GenTree* tree, var_types dstTyp, bool isUnsigned = false); GenTree* impImplicitR4orR8Cast(GenTree* tree, var_types dstTyp); diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index c3bf24ce6d006..f0fbf09f4cbf1 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -3171,15 +3171,25 @@ void Compiler::impBashVarAddrsToI(GenTree* tree1, GenTree* tree2) } } -/***************************************************************************** - * TYP_INT and TYP_I_IMPL can be used almost interchangeably, but we want - * to make that an explicit cast in our trees, so any implicit casts that - * exist in the IL (at least on 64-bit where TYP_I_IMPL != TYP_INT) are - * turned into explicit casts here. - * We also allow an implicit conversion of a ldnull into a TYP_I_IMPL(0) - */ +//------------------------------------------------------------------------ +// impImplicitIorI4Cast: Adds an explicit cast to TYP_INT or TYP_I_IMPL +// +// Arguments: +// tree - node to cast +// dstTyp - cast type +// isUnsigned - is node known to be unsigned? +// +// Return Value: +// A new tree surrounded with a cast op if needed +// +// Notes: +// TYP_INT and TYP_I_IMPL can be used almost interchangeably, but we want +// to make that an explicit cast in our trees, so any implicit casts that +// exist in the IL(at least on 64 - bit where TYP_I_IMPL != TYP_INT) are +// turned into explicit casts here. +// We also allow an implicit conversion of a ldnull into a TYP_I_IMPL(0) -GenTree* Compiler::impImplicitIorI4Cast(GenTree* tree, var_types dstTyp) +GenTree* Compiler::impImplicitIorI4Cast(GenTree* tree, var_types dstTyp, bool isUnsigned) { var_types currType = genActualType(tree->gtType); var_types wantedType = genActualType(dstTyp); @@ -3198,12 +3208,12 @@ GenTree* Compiler::impImplicitIorI4Cast(GenTree* tree, var_types dstTyp) else if (varTypeIsI(wantedType) && (currType == TYP_INT)) { // Note that this allows TYP_INT to be cast to a TYP_I_IMPL when wantedType is a TYP_BYREF or TYP_REF - tree = gtNewCastNode(TYP_I_IMPL, tree, false, TYP_I_IMPL); + tree = gtNewCastNode(TYP_I_IMPL, tree, isUnsigned, TYP_I_IMPL); } else if ((wantedType == TYP_INT) && varTypeIsI(currType)) { // Note that this allows TYP_BYREF or TYP_REF to be cast to a TYP_INT - tree = gtNewCastNode(TYP_INT, tree, false, TYP_INT); + tree = gtNewCastNode(TYP_INT, tree, isUnsigned, TYP_INT); } #endif // TARGET_64BIT } @@ -4152,7 +4162,7 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, GenTreeBoundsChk(GT_ARR_BOUNDS_CHECK, TYP_VOID, index, length, SCK_RNGCHK_FAIL); // Element access - GenTree* indexIntPtr = impImplicitIorI4Cast(indexClone, TYP_I_IMPL); + GenTree* indexIntPtr = impImplicitIorI4Cast(indexClone, TYP_I_IMPL, /*isUnsigned:*/ true); GenTree* sizeofNode = gtNewIconNode(elemSize); GenTree* mulNode = gtNewOperNode(GT_MUL, TYP_I_IMPL, indexIntPtr, sizeofNode); CORINFO_FIELD_HANDLE ptrHnd = info.compCompHnd->getFieldInClass(clsHnd, 0); diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 9e8f37e081933..e233f3b309b82 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -5626,7 +5626,9 @@ GenTree* Compiler::fgMorphArrayIndex(GenTree* tree) } else { - index = gtNewCastNode(TYP_I_IMPL, index, false, TYP_I_IMPL); + // Mark cast as unsigned since index is never negative + // at this point (handled by GT_ARR_BOUNDS_CHECK) + index = gtNewCastNode(TYP_I_IMPL, index, true, TYP_I_IMPL); } } #endif // TARGET_64BIT