From af4287f2e0f33afdfe5ed0d70da7c4ae3024fb4f Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 8 Feb 2024 11:08:17 +0100 Subject: [PATCH 1/2] Add test --- .../JitBlue/Runtime_93876/Runtime_93876.cs | 25 +++++++++++++++++++ .../Runtime_93876/Runtime_93876.csproj | 8 ++++++ 2 files changed, 33 insertions(+) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.csproj diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.cs b/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.cs new file mode 100644 index 00000000000000..760cd04a594e3e --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using System.Runtime.Intrinsics; +using System.Numerics; +using Xunit; + +public static class Runtime_93876 +{ + [Fact] + public static void Problem() + { + Vector4 v = Mul(0, 1); + Assert.Equal(Vector4.One, v); + Vector64 v64 = Mul64(0, 1); + Assert.Equal(Vector64.One, v64); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector4 Mul(float a, float b) => Vector4.Multiply(a + b, Vector4.One); + + [MethodImpl(MethodImplOptions.NoInlining)] + private static Vector64 Mul64(float a, float b) => Vector64.Multiply(a + b, Vector64.One); +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.csproj new file mode 100644 index 00000000000000..15edd99711a1a4 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_93876/Runtime_93876.csproj @@ -0,0 +1,8 @@ + + + True + + + + + \ No newline at end of file From 9a06a7a665c5ed0b905131469fc5f55bcc34a932 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Thu, 8 Feb 2024 11:09:18 +0100 Subject: [PATCH 2/2] Add bugfix --- src/coreclr/jit/valuenum.cpp | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 6943c3c5e07e26..364f71d13219d0 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -7734,10 +7734,38 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunBinary(var_types type, } #ifdef TARGET_ARM64 - case NI_AdvSimd_Multiply: case NI_AdvSimd_MultiplyByScalar: - case NI_AdvSimd_Arm64_Multiply: case NI_AdvSimd_Arm64_MultiplyByScalar: + { + if (!varTypeIsFloating(baseType)) + { + // Handle `x * 0 == 0` and `0 * x == 0` + // Not safe for floating-point when x == -0.0, NaN, +Inf, -Inf + ValueNum zeroVN = VNZeroForType(TypeOfVN(cnsVN)); + + if (cnsVN == zeroVN) + { + return VNZeroForType(type); + } + } + + assert((TypeOfVN(arg0VN) == type) && (TypeOfVN(arg1VN) == TYP_SIMD8)); + + // Handle x * 1 => x, but only if the scalar RHS is <1, ...>. + if (IsVNConstant(arg1VN)) + { + if (EvaluateSimdGetElement(this, TYP_SIMD8, baseType, arg1VN, 0) == VNOneForType(baseType)) + { + return arg0VN; + } + } + break; + } +#endif + +#ifdef TARGET_ARM64 + case NI_AdvSimd_Multiply: + case NI_AdvSimd_Arm64_Multiply: #else case NI_SSE_Multiply: case NI_SSE2_Multiply: