From be188e876579e967fa04581e7e6fa5d47f36b63e Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Wed, 13 May 2026 18:22:42 +0300 Subject: [PATCH 1/2] Match jit behavior when converting float/double to u1/u2 Previously it converted first to uint32_t, which was doing a saturating conversion. Example: Before (ushort)-4567.0f = (ushort)(uint)-4567.0f = (ushort)0 = 0 After (ushort)-4567.0f = (ushort)(int)-4567.0f = (ushort)-4567 = 60969 Fixes System.Runtime.InteropServices.Tests.NFloatTests.NFloatTo* tests on interpreter --- src/coreclr/vm/interpexec.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index 92bc3638ccb124..0dd6c9848569c1 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -1613,11 +1613,11 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 3; break; case INTOP_CONV_U1_R4: - ConvFpHelper(stack, ip); + ConvFpHelper(stack, ip); ip += 3; break; case INTOP_CONV_U1_R8: - ConvFpHelper(stack, ip); + ConvFpHelper(stack, ip); ip += 3; break; case INTOP_CONV_I2_I4: @@ -1645,11 +1645,11 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 3; break; case INTOP_CONV_U2_R4: - ConvFpHelper(stack, ip); + ConvFpHelper(stack, ip); ip += 3; break; case INTOP_CONV_U2_R8: - ConvFpHelper(stack, ip); + ConvFpHelper(stack, ip); ip += 3; break; case INTOP_CONV_I4_R4: From c6f71ef4f01c426a4549e8a0e5eb4c2991ccc30f Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Mon, 18 May 2026 17:15:59 +0300 Subject: [PATCH 2/2] Fix ConvertToIntegerTest and disable it on CoreCLR IFloatingPoint.ConvertToInteger are always saturating. Jit fails this test because id doesn't follow the managed implementation, intrinsifying instead with non-saturating implementation. --- .../System/DoubleTests.GenericMath.cs | 11 ++++++----- .../System/SingleTests.GenericMath.cs | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.GenericMath.cs index 153d4fdf22a729..8a1b2747889b0f 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/DoubleTests.GenericMath.cs @@ -346,17 +346,18 @@ public static void op_InequalityTest() [Fact] [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/116823", typeof(PlatformDetection), nameof(PlatformDetection.IsCoreClrInterpreter))] + // Passes on the interpreter, but interpreter configurations might still use jit fallback + [ActiveIssue("https://github.com/dotnet/runtime/issues/116823", typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime))] public static void ConvertToIntegerTest() { // Signed Values - Assert.Equal(0, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(short.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); Assert.Equal(int.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); Assert.Equal(long.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); Assert.Equal(Int128.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); Assert.Equal(nint.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); - Assert.Equal(0, FloatingPointHelper.ConvertToInteger(double.MinValue)); + Assert.Equal(sbyte.MinValue, FloatingPointHelper.ConvertToInteger(double.MinValue)); Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6)); Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6)); @@ -365,12 +366,12 @@ public static void ConvertToIntegerTest() Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6)); Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6)); - Assert.Equal(-1, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(short.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); Assert.Equal(int.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); Assert.Equal(long.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); Assert.Equal(Int128.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); Assert.Equal(nint.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); - Assert.Equal(-1, FloatingPointHelper.ConvertToInteger(double.MaxValue)); + Assert.Equal(sbyte.MaxValue, FloatingPointHelper.ConvertToInteger(double.MaxValue)); // Unsigned Values diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.GenericMath.cs index 407cb6c41164ad..ad19ea63e61b5d 100644 --- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.GenericMath.cs +++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SingleTests.GenericMath.cs @@ -346,17 +346,18 @@ public static void op_InequalityTest() [Fact] [SkipOnMono("https://github.com/dotnet/runtime/issues/100368")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/116823", typeof(PlatformDetection), nameof(PlatformDetection.IsCoreClrInterpreter))] + // Passes on the interpreter, but interpreter configurations might still use jit fallback + [ActiveIssue("https://github.com/dotnet/runtime/issues/116823", typeof(PlatformDetection), nameof(PlatformDetection.IsNotMonoRuntime))] public static void ConvertToIntegerTest() { // Signed Values - Assert.Equal(0, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(short.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); Assert.Equal(int.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); Assert.Equal(long.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); Assert.Equal(Int128.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); Assert.Equal(nint.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); - Assert.Equal(0, FloatingPointHelper.ConvertToInteger(float.MinValue)); + Assert.Equal(sbyte.MinValue, FloatingPointHelper.ConvertToInteger(float.MinValue)); Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6f)); Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6f)); @@ -365,12 +366,12 @@ public static void ConvertToIntegerTest() Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6f)); Assert.Equal(2, FloatingPointHelper.ConvertToInteger(2.6f)); - Assert.Equal(-1, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(short.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); Assert.Equal(int.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); Assert.Equal(long.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); Assert.Equal(Int128.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); Assert.Equal(nint.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); - Assert.Equal(-1, FloatingPointHelper.ConvertToInteger(float.MaxValue)); + Assert.Equal(sbyte.MaxValue, FloatingPointHelper.ConvertToInteger(float.MaxValue)); // Unsigned Values