diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index be7fc14611f0f8..f32b7d79ddb0b9 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -2869,13 +2869,15 @@ ValueNum ValueNumStore::EvalFuncForConstantArgs(var_types typ, VNFunc func, Valu { int resVal = EvalOp(func, ConstantValue(arg0VN)); // Unary op on a handle results in a handle. - return IsVNHandle(arg0VN) ? VNForHandle(ssize_t(resVal), GetHandleFlags(arg0VN)) : VNForIntCon(resVal); + return IsVNHandle(arg0VN) ? VNForHandle(ssize_t(resVal), GetFoldedArithOpResultHandleFlags(arg0VN)) + : VNForIntCon(resVal); } case TYP_LONG: { INT64 resVal = EvalOp(func, ConstantValue(arg0VN)); // Unary op on a handle results in a handle. - return IsVNHandle(arg0VN) ? VNForHandle(ssize_t(resVal), GetHandleFlags(arg0VN)) : VNForLongCon(resVal); + return IsVNHandle(arg0VN) ? VNForHandle(ssize_t(resVal), GetFoldedArithOpResultHandleFlags(arg0VN)) + : VNForLongCon(resVal); } case TYP_FLOAT: { @@ -3106,7 +3108,7 @@ ValueNum ValueNumStore::EvalFuncForConstantArgs(var_types typ, VNFunc func, Valu ValueNum handleVN = IsVNHandle(arg0VN) ? arg0VN : IsVNHandle(arg1VN) ? arg1VN : NoVN; if (handleVN != NoVN) { - result = VNForHandle(ssize_t(resultVal), GetHandleFlags(handleVN)); // Use VN for Handle + result = VNForHandle(ssize_t(resultVal), GetFoldedArithOpResultHandleFlags(handleVN)); } else { @@ -3132,7 +3134,7 @@ ValueNum ValueNumStore::EvalFuncForConstantArgs(var_types typ, VNFunc func, Valu if (handleVN != NoVN) { - result = VNForHandle(ssize_t(resultVal), GetHandleFlags(handleVN)); // Use VN for Handle + result = VNForHandle(ssize_t(resultVal), GetFoldedArithOpResultHandleFlags(handleVN)); } else { @@ -5119,6 +5121,37 @@ GenTreeFlags ValueNumStore::GetHandleFlags(ValueNum vn) return handle->m_flags; } +GenTreeFlags ValueNumStore::GetFoldedArithOpResultHandleFlags(ValueNum vn) +{ + GenTreeFlags flags = GetHandleFlags(vn); + assert((flags & GTF_ICON_HDL_MASK) == flags); + + switch (flags) + { + case GTF_ICON_SCOPE_HDL: + case GTF_ICON_CLASS_HDL: + case GTF_ICON_METHOD_HDL: + case GTF_ICON_FIELD_HDL: + case GTF_ICON_TOKEN_HDL: + case GTF_ICON_STR_HDL: + case GTF_ICON_CONST_PTR: + case GTF_ICON_VARG_HDL: + case GTF_ICON_PINVKI_HDL: + case GTF_ICON_FTN_ADDR: + case GTF_ICON_CIDMID_HDL: + case GTF_ICON_TLS_HDL: + case GTF_ICON_STATIC_BOX_PTR: + return GTF_ICON_CONST_PTR; + case GTF_ICON_STATIC_HDL: + case GTF_ICON_GLOBAL_PTR: + case GTF_ICON_BBC_PTR: + return GTF_ICON_GLOBAL_PTR; + default: + assert(!"Unexpected handle type"); + return flags; + } +} + bool ValueNumStore::IsVNHandle(ValueNum vn) { if (vn == NoVN) diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h index 22755856066a7d..fc9ed09913c630 100644 --- a/src/coreclr/jit/valuenum.h +++ b/src/coreclr/jit/valuenum.h @@ -379,6 +379,8 @@ class ValueNumStore // returns true iff vn is known to be a constant int32 that is > 0 bool IsVNPositiveInt32Constant(ValueNum vn); + GenTreeFlags GetFoldedArithOpResultHandleFlags(ValueNum vn); + public: // Initializes any static variables of ValueNumStore. static void InitValueNumStoreStatics();