diff --git a/src/coreclr/jit/optcse.cpp b/src/coreclr/jit/optcse.cpp index 4e7fc81df64bc..505352250f4ec 100644 --- a/src/coreclr/jit/optcse.cpp +++ b/src/coreclr/jit/optcse.cpp @@ -3066,8 +3066,11 @@ class CSE_Heuristic assert(vnStore->IsVNCompareCheckedBoundArith(oldCmpVN)); vnStore->GetCompareCheckedBoundArithInfo(oldCmpVN, &info); - newCmpArgVN = vnStore->VNForFunc(vnStore->TypeOfVN(info.arrOp), (VNFunc)info.arrOper, - info.arrOp, theConservativeVN); + ValueNum arrOp1 = info.arrOpLHS ? info.arrOp : theConservativeVN; + ValueNum arrOp2 = info.arrOpLHS ? theConservativeVN : info.arrOp; + + newCmpArgVN = + vnStore->VNForFunc(vnStore->TypeOfVN(info.arrOp), (VNFunc)info.arrOper, arrOp1, arrOp2); } ValueNum newCmpVN = vnStore->VNForFunc(vnStore->TypeOfVN(oldCmpVN), (VNFunc)info.cmpOper, info.cmpOp, newCmpArgVN); diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index fa60633afbc23..fbc80330eb92f 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -6576,15 +6576,17 @@ void ValueNumStore::GetCheckedBoundArithInfo(ValueNum vn, CompareCheckedBoundAri bool isOp1CheckedBound = IsVNCheckedBound(funcArith.m_args[1]); if (isOp1CheckedBound) { - info->arrOper = funcArith.m_func; - info->arrOp = funcArith.m_args[0]; - info->vnBound = funcArith.m_args[1]; + info->arrOper = funcArith.m_func; + info->arrOp = funcArith.m_args[0]; + info->vnBound = funcArith.m_args[1]; + info->arrOpLHS = true; } else { - info->arrOper = funcArith.m_func; - info->arrOp = funcArith.m_args[1]; - info->vnBound = funcArith.m_args[0]; + info->arrOper = funcArith.m_func; + info->arrOp = funcArith.m_args[1]; + info->vnBound = funcArith.m_args[0]; + info->arrOpLHS = false; } } diff --git a/src/coreclr/jit/valuenum.h b/src/coreclr/jit/valuenum.h index 04fed7bfbc1f6..af6ba52901483 100644 --- a/src/coreclr/jit/valuenum.h +++ b/src/coreclr/jit/valuenum.h @@ -920,9 +920,10 @@ class ValueNumStore ValueNum vnBound; unsigned arrOper; ValueNum arrOp; + bool arrOpLHS; // arrOp is on the left side of cmpOp expression unsigned cmpOper; ValueNum cmpOp; - CompareCheckedBoundArithInfo() : vnBound(NoVN), arrOper(GT_NONE), arrOp(NoVN), cmpOper(GT_NONE), cmpOp(NoVN) + CompareCheckedBoundArithInfo() : vnBound(NoVN), arrOper(GT_NONE), arrOp(NoVN), arrOpLHS(false), cmpOper(GT_NONE), cmpOp(NoVN) { } #ifdef DEBUG diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.cs b/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.cs new file mode 100644 index 0000000000000..e7c94f11ac2dc --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Runtime.CompilerServices; +using Xunit; + +public static class Runtime_100809 +{ + [Fact] + public static int TestEntryPoint() + { + return AlwaysFalse(96) ? -1 : 100; + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static bool AlwaysFalse(int x) + { + var result = new byte[x]; + int count = result.Length - 2; + return (x < 0 || result.Length - count < 0); + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.csproj new file mode 100644 index 0000000000000..197767e2c4e24 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_100809/Runtime_100809.csproj @@ -0,0 +1,5 @@ + + + + +