diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index f3a40e19bcfe..bbf6d59c4f95 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -5796,6 +5796,11 @@ bool ValueNumStore::IsVNConstant(ValueNum vn) } } +bool ValueNumStore::IsVNConstantNonHandle(ValueNum vn) +{ + return IsVNConstant(vn) && !IsVNHandle(vn); +} + bool ValueNumStore::IsVNInt32Constant(ValueNum vn) { if (!IsVNConstant(vn)) @@ -10379,38 +10384,37 @@ static bool GetObjectHandleAndOffset(ValueNumStore* vnStore, ssize_t* byteOffset, CORINFO_OBJECT_HANDLE* pObj) { - if (!tree->gtVNPair.BothEqual()) { return false; } - ValueNum treeVN = tree->gtVNPair.GetLiberal(); - VNFuncApp funcApp; - if (vnStore->GetVNFunc(treeVN, &funcApp) && (funcApp.m_func == (VNFunc)GT_ADD)) + ValueNum treeVN = tree->gtVNPair.GetLiberal(); + VNFuncApp funcApp; + target_ssize_t offset = 0; + while (vnStore->GetVNFunc(treeVN, &funcApp) && (funcApp.m_func == (VNFunc)GT_ADD)) { - // [objHandle + offset] - if (vnStore->IsVNObjHandle(funcApp.m_args[0]) && vnStore->IsVNConstant(funcApp.m_args[1])) + if (vnStore->IsVNConstantNonHandle(funcApp.m_args[0]) && (vnStore->TypeOfVN(funcApp.m_args[0]) == TYP_I_IMPL)) { - *pObj = vnStore->ConstantObjHandle(funcApp.m_args[0]); - *byteOffset = vnStore->ConstantValue(funcApp.m_args[1]); - return true; + offset += vnStore->ConstantValue(funcApp.m_args[0]); + treeVN = funcApp.m_args[1]; } - - // [offset + objHandle] - // TODO: Introduce a general helper to accumulate offsets for - // shapes such as (((X + CNS1) + CNS2) + CNS3) etc. - if (vnStore->IsVNObjHandle(funcApp.m_args[1]) && vnStore->IsVNConstant(funcApp.m_args[0])) + else if (vnStore->IsVNConstantNonHandle(funcApp.m_args[1]) && + (vnStore->TypeOfVN(funcApp.m_args[1]) == TYP_I_IMPL)) { - *pObj = vnStore->ConstantObjHandle(funcApp.m_args[1]); - *byteOffset = vnStore->ConstantValue(funcApp.m_args[0]); - return true; + offset += vnStore->ConstantValue(funcApp.m_args[1]); + treeVN = funcApp.m_args[0]; + } + else + { + return false; } } - else if (vnStore->IsVNObjHandle(treeVN)) + + if (vnStore->IsVNObjHandle(treeVN)) { *pObj = vnStore->ConstantObjHandle(treeVN); - *byteOffset = 0; + *byteOffset = offset; return true; } return false; diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h index d01550081822..5d598523c2e8 100644 --- a/src/coreclr/jit/valuenum.h +++ b/src/coreclr/jit/valuenum.h @@ -858,9 +858,12 @@ class ValueNumStore // Returns BasicBlock::MAX_LOOP_NUM if the given value number's loop nest is unknown or ill-defined. BasicBlock::loopNumber LoopOfVN(ValueNum vn); - // Returns true iff the VN represents a (non-handle) constant. + // Returns true iff the VN represents a constant. bool IsVNConstant(ValueNum vn); + // Returns true iff the VN represents a (non-handle) constant. + bool IsVNConstantNonHandle(ValueNum vn); + // Returns true iff the VN represents an integer constant. bool IsVNInt32Constant(ValueNum vn); diff --git a/src/libraries/System.Private.CoreLib/src/System/Boolean.cs b/src/libraries/System.Private.CoreLib/src/System/Boolean.cs index 144157c25940..358d7c8db3ac 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Boolean.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Boolean.cs @@ -236,8 +236,14 @@ public static bool Parse(string value) return Parse(value.AsSpan()); } - public static bool Parse(ReadOnlySpan value) => - TryParse(value, out bool result) ? result : throw new FormatException(SR.Format(SR.Format_BadBoolean, new string(value))); + public static bool Parse(ReadOnlySpan value) + { + if (!TryParse(value, out bool result)) + { + ThrowHelper.ThrowFormatException_BadBoolean(value); + } + return result; + } // Determines whether a String represents true or false. // @@ -267,6 +273,7 @@ public static bool TryParse(ReadOnlySpan value, out bool result) return TryParseUncommon(value, out result); + [MethodImpl(MethodImplOptions.NoInlining)] static bool TryParseUncommon(ReadOnlySpan value, out bool result) { // With "true" being 4 characters, even if we trim something from <= 4 chars, diff --git a/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs b/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs index 95c49059600b..3f4ae02f9bef 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs @@ -539,6 +539,12 @@ internal static void ThrowFormatException_NeedSingleChar() throw new FormatException(SR.Format_NeedSingleChar); } + [DoesNotReturn] + internal static void ThrowFormatException_BadBoolean(ReadOnlySpan value) + { + throw new FormatException(SR.Format(SR.Format_BadBoolean, new string(value))); + } + [DoesNotReturn] internal static void ThrowArgumentOutOfRangeException_PrecisionTooLarge() {