diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 921a34fa057fbb..0532f8df795345 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -1084,7 +1084,18 @@ struct GenTree bool IsNotGcDef() const { - return IsIntegralConst(0) || OperIs(GT_LCL_ADDR); + if (IsIntegralConst(0) || OperIs(GT_LCL_ADDR)) + { + return true; + } + + // Any NonGC object or NonGC object + any offset. + if (IsIconHandle(GTF_ICON_OBJ_HDL) || (OperIs(GT_ADD) && gtGetOp1()->IsIconHandle(GTF_ICON_OBJ_HDL))) + { + return true; + } + + return false; } // LIR flags diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 52ac0df5d4cb71..19a34dba7f6bf6 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -15215,8 +15215,25 @@ void ValueNumStore::PeelOffsets(ValueNum* vn, target_ssize_t* offset) *offset = 0; VNFuncApp app; - while (GetVNFunc(*vn, &app) && (app.m_func == VNF_ADD)) + while (GetVNFunc(*vn, &app) && ((app.m_func == VNF_ADD) || (app.m_func == VNF_Cast))) { + if (app.m_func == VNF_Cast) + { + // Ignore GC -> I_IMPL casts during peeling + if (TypeOfVN(*vn) == TYP_I_IMPL) + { + var_types castToType; + bool srcIsUnsigned; + GetCastOperFromVN(app.m_args[1], &castToType, &srcIsUnsigned); + if (varTypeIsI(castToType) && varTypeIsI(TypeOfVN(app.m_args[0]))) + { + *vn = app.m_args[0]; + continue; + } + } + break; + } + // We don't treat handles and null as constant offset. if (IsVNConstantNonHandle(app.m_args[0]) && (app.m_args[0] != VNForNull()))