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: 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