From 94fe5263ecb0ba0d7979402bd7558152457e0651 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Sun, 7 Jun 2026 08:54:42 -0700 Subject: [PATCH 1/2] JIT: remove unsound NOT(relop) VN simplification VNForFunc was rewriting NOT(relop(x,y)) to Reverse(relop)(x,y). GT_NOT is bitwise complement, not logical negation: for a 0/1 relop result, `~v` produces -1 or -2, not the 1 or 0 that the reversed relop would, so downstream arithmetic uses of the complemented value folded the wrong way. Fixes #129076. --- src/coreclr/jit/valuenum.cpp | 6 ---- .../JitBlue/Runtime_129076/Runtime_129076.cs | 36 +++++++++++++++++++ .../Runtime_129076/Runtime_129076.csproj | 8 +++++ 3 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.csproj diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index e657b9dde198f5..55a450d2932478 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -2575,12 +2575,6 @@ ValueNum ValueNumStore::VNForFunc(var_types typ, VNFunc func, ValueNum arg0VN) { *resultVN = funcApp.GetArg(0); } - // NOT(relop(x,y)) ==> Reverse(relop)(x,y) - // - else if (VNFuncIsComparison(funcApp.GetFunc())) - { - *resultVN = GetRelatedRelop(arg0VN, VN_RELATION_KIND::VRK_Reverse); - } } } diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.cs b/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.cs new file mode 100644 index 00000000000000..e53d877c902ba9 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +// VN was simplifying NOT(relop(x,y)) to Reverse(relop)(x,y). GT_NOT is +// bitwise complement, not logical negation: ~(x relop y) produces -1 or +// -2 for a 0/1 relop result, while Reverse(relop)(x,y) produces 0 or 1, +// so downstream uses comparing the value arithmetically (here `~v3 >= -1`) +// folded the wrong way. + +using System.Runtime.CompilerServices; +using Xunit; + +public static class Runtime_129076 +{ + private static volatile int Input_p0 = unchecked((int)0x800335C5); + private static volatile int Input_p1 = 0; + + [MethodImpl(MethodImplOptions.NoInlining)] + public static int Func(int p0, int p1) + { + unchecked + { + int v1 = unchecked((int)0x000335C5) & p1; + int v3 = (v1 != p0) ? 1 : 0; + if (v3 == 0) return 99; + int v4 = ~v3; + return (v4 >= -1) ? 1 : 0; + } + } + + [Fact] + public static int TestEntryPoint() + { + return Func(Input_p0, Input_p1) == 0 ? 100 : 1; + } +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.csproj new file mode 100644 index 00000000000000..de6d5e08882e86 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.csproj @@ -0,0 +1,8 @@ + + + True + + + + + From 2ee3d30de68fcbb3cf645f115c0d4f05121eacdf Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Sun, 7 Jun 2026 11:35:56 -0700 Subject: [PATCH 2/2] Wire Runtime_129076 into Regression_ro_2 merged runner Drop the standalone .csproj and add the .cs to Regression_ro_2.csproj following the pattern of recent JitBlue tests (Runtime_128631, Runtime_128801). Standalone csprojs are only needed when the test requires its own process via CLRTestEnvironmentVariable; ours doesn't. Verified: bash Regression_ro_2.sh invokes Runtime_129076.TestEntryPoint (passes on the fixed JIT, fails on the regressed JIT). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../Regression/JitBlue/Runtime_129076/Runtime_129076.cs | 2 ++ .../JitBlue/Runtime_129076/Runtime_129076.csproj | 8 -------- src/tests/JIT/Regression/Regression_ro_2.csproj | 1 + 3 files changed, 3 insertions(+), 8 deletions(-) delete mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.csproj diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.cs b/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.cs index e53d877c902ba9..d593f7e4e35f5a 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.cs @@ -7,6 +7,8 @@ // so downstream uses comparing the value arithmetically (here `~v3 >= -1`) // folded the wrong way. +namespace Runtime_129076; + using System.Runtime.CompilerServices; using Xunit; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.csproj deleted file mode 100644 index de6d5e08882e86..00000000000000 --- a/src/tests/JIT/Regression/JitBlue/Runtime_129076/Runtime_129076.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - True - - - - - diff --git a/src/tests/JIT/Regression/Regression_ro_2.csproj b/src/tests/JIT/Regression/Regression_ro_2.csproj index f8bedd81f9050b..82e13ec3df7e5c 100644 --- a/src/tests/JIT/Regression/Regression_ro_2.csproj +++ b/src/tests/JIT/Regression/Regression_ro_2.csproj @@ -100,6 +100,7 @@ +