[release/8.0-rc2] Ensure that embedded broadcast checks the base type of the parent...
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Fri, 22 Sep 2023 17:14:27 +0000 (10:14 -0700)
committerGitHub <noreply@github.com>
Fri, 22 Sep 2023 17:14:27 +0000 (10:14 -0700)
* Ensure that embedded broadcast checks the base type of the parent node

* Ensure the regression test exits if AVX2 is not supported

* Also handle embedded broadcasts for mismatched memory sizes

---------

Co-authored-by: Tanner Gooding <tagoo@outlook.com>
src/coreclr/jit/lowerxarch.cpp
src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.cs [new file with mode: 0644]
src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.csproj [new file with mode: 0644]

index 30c2a832b94fc18cae22051ddd09f7f70b26357a..319238aaec628fb91d0b8c78b925d6d34e5d7173 100644 (file)
@@ -8202,10 +8202,12 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre
         case NI_AVX2_BroadcastScalarToVector256:
         case NI_AVX512F_BroadcastScalarToVector512:
         {
-            var_types baseType = hwintrinsic->GetSimdBaseType();
-            if (varTypeIsSmall(baseType))
+            var_types parentBaseType = parentNode->GetSimdBaseType();
+            var_types childBaseType  = hwintrinsic->GetSimdBaseType();
+
+            if (varTypeIsSmall(parentBaseType) || (genTypeSize(parentBaseType) != genTypeSize(childBaseType)))
             {
-                // early return if the base type is not embedded broadcast compatible.
+                // early return if either base type is not embedded broadcast compatible.
                 return false;
             }
 
@@ -8213,7 +8215,7 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre
             if (intrinsicId == NI_SSE3_MoveAndDuplicate)
             {
                 // NI_SSE3_MoveAndDuplicate is for Vector128<double> only.
-                assert(baseType == TYP_DOUBLE);
+                assert(childBaseType == TYP_DOUBLE);
             }
 
             if (comp->compOpportunisticallyDependsOn(InstructionSet_AVX512F_VL) &&
@@ -8246,6 +8248,15 @@ bool Lowering::IsContainableHWIntrinsicOp(GenTreeHWIntrinsic* parentNode, GenTre
         case NI_AVX_BroadcastScalarToVector128:
         case NI_AVX_BroadcastScalarToVector256:
         {
+            var_types parentBaseType = parentNode->GetSimdBaseType();
+            var_types childBaseType  = hwintrinsic->GetSimdBaseType();
+
+            if (varTypeIsSmall(parentBaseType) || (genTypeSize(parentBaseType) != genTypeSize(childBaseType)))
+            {
+                // early return if either base type is not embedded broadcast compatible.
+                return false;
+            }
+
             return parentNode->OperIsEmbBroadcastCompatible();
         }
 
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.cs b/src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.cs
new file mode 100644 (file)
index 0000000..4704441
--- /dev/null
@@ -0,0 +1,47 @@
+// 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 System.Runtime.Intrinsics;
+using System.Runtime.Intrinsics.X86;
+using Xunit;
+
+public static class Runtime_92357
+{
+    [Fact]
+    [MethodImpl(MethodImplOptions.AggressiveOptimization)]
+    public static void Problem()
+    {
+        if (!Avx2.IsSupported)
+        {
+            return;
+        }
+
+        int y1 = 5;
+
+        Vector256<short> actual1 = Test1(Vector256.Create((short)1), ref y1);
+        Vector256<short> expected1 = Vector256.Create(10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0, 10, 0);
+
+        Assert.Equal(expected1, actual1);
+
+        long y2 = 5;
+
+        Vector256<int> actual2 = Test2(Vector256.Create((int)1), ref y2);
+        Vector256<int> expected2 = Vector256.Create(10, 0, 10, 0, 10, 0, 10, 0);
+
+        Assert.Equal(expected2, actual2);
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
+    public static Vector256<short> Test1(Vector256<short> x, ref int y)
+    {
+        return Avx2.MultiplyLow(x + x, Vector256.Create(y).AsInt16());
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
+    public static Vector256<int> Test2(Vector256<int> x, ref long y)
+    {
+        return Avx2.MultiplyLow(x + x, Vector256.Create(y).AsInt32());
+    }
+}
diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_92357/Runtime_92357.csproj
new file mode 100644 (file)
index 0000000..15edd99
--- /dev/null
@@ -0,0 +1,8 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <Optimize>True</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildProjectName).cs" />
+  </ItemGroup>
+</Project>
\ No newline at end of file