RyuJIT: Fix logic to test bits in a constant vector (Vector256) (#47385)
authorEgor Bogatov <egorbo@gmail.com>
Tue, 16 Feb 2021 18:35:22 +0000 (21:35 +0300)
committerGitHub <noreply@github.com>
Tue, 16 Feb 2021 18:35:22 +0000 (21:35 +0300)
Co-authored-by: Sergey Andreenko <seandree@microsoft.com>
src/coreclr/jit/lower.h
src/coreclr/jit/lowerarmarch.cpp
src/coreclr/jit/lowerxarch.cpp
src/tests/JIT/HardwareIntrinsics/General/Regression/GitHub_47236/GitHub_47236.cs [new file with mode: 0644]
src/tests/JIT/HardwareIntrinsics/General/Regression/GitHub_47236/GitHub_47236.csproj [new file with mode: 0644]
src/tests/issues.targets

index c8500c0..83ce67d 100644 (file)
@@ -349,6 +349,28 @@ private:
     };
 
     //----------------------------------------------------------------------------------------------
+    // VectorConstantIsBroadcastedI64: Check N i64 elements in a constant vector for equality
+    //
+    //  Arguments:
+    //     vecCns  - Constant vector
+    //     count   - Amount of i64 components to compare
+    //
+    //  Returns:
+    //     true if N i64 elements of the given vector are equal
+    static bool VectorConstantIsBroadcastedI64(VectorConstant& vecCns, int count)
+    {
+        assert(count >= 1 && count <= 4);
+        for (int i = 1; i < count; i++)
+        {
+            if (vecCns.i64[i] != vecCns.i64[0])
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    //----------------------------------------------------------------------------------------------
     // ProcessArgForHWIntrinsicCreate: Processes an argument for the Lowering::LowerHWIntrinsicCreate method
     //
     //  Arguments:
index 430d680..cf5d6e3 100644 (file)
@@ -971,25 +971,23 @@ void Lowering::LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node)
 
         assert((simdSize == 8) || (simdSize == 16));
 
-        if ((argCnt == 1) || (simdSize == 8) || (vecCns.i64[0] == vecCns.i64[1]))
+        if (VectorConstantIsBroadcastedI64(vecCns, simdSize / 8))
         {
             // If we are a single constant or if all parts are the same, we might be able to optimize
             // this even further for certain values, such as Zero or AllBitsSet.
 
             if (vecCns.i64[0] == 0)
             {
-                node->gtOp1 = nullptr;
-                node->gtOp2 = nullptr;
-
-                node->gtHWIntrinsicId = NI_Vector128_get_Zero;
+                node->gtOp1           = nullptr;
+                node->gtOp2           = nullptr;
+                node->gtHWIntrinsicId = (simdSize == 8) ? NI_Vector64_get_Zero : NI_Vector128_get_Zero;
                 return;
             }
             else if (vecCns.i64[0] == -1)
             {
-                node->gtOp1 = nullptr;
-                node->gtOp2 = nullptr;
-
-                node->gtHWIntrinsicId = NI_Vector128_get_AllBitsSet;
+                node->gtOp1           = nullptr;
+                node->gtOp2           = nullptr;
+                node->gtHWIntrinsicId = (simdSize == 8) ? NI_Vector64_get_AllBitsSet : NI_Vector128_get_AllBitsSet;
                 return;
             }
         }
index 4c6ace9..98aa897 100644 (file)
@@ -1517,26 +1517,23 @@ void Lowering::LowerHWIntrinsicCreate(GenTreeHWIntrinsic* node)
 
         assert((simdSize == 8) || (simdSize == 12) || (simdSize == 16) || (simdSize == 32));
 
-        if ((argCnt == 1) ||
-            ((vecCns.i64[0] == vecCns.i64[1]) && ((simdSize <= 16) || (vecCns.i64[2] == vecCns.i64[3]))))
+        if (((simdSize == 16) || (simdSize == 32)) && VectorConstantIsBroadcastedI64(vecCns, simdSize / 8))
         {
             // If we are a single constant or if all parts are the same, we might be able to optimize
             // this even further for certain values, such as Zero or AllBitsSet.
 
             if (vecCns.i64[0] == 0)
             {
-                node->gtOp1 = nullptr;
-                node->gtOp2 = nullptr;
-
-                node->gtHWIntrinsicId = NI_Vector128_get_Zero;
+                node->gtOp1           = nullptr;
+                node->gtOp2           = nullptr;
+                node->gtHWIntrinsicId = (simdSize == 16) ? NI_Vector128_get_Zero : NI_Vector256_get_Zero;
                 return;
             }
             else if (vecCns.i64[0] == -1)
             {
-                node->gtOp1 = nullptr;
-                node->gtOp2 = nullptr;
-
-                node->gtHWIntrinsicId = NI_Vector128_get_AllBitsSet;
+                node->gtOp1           = nullptr;
+                node->gtOp2           = nullptr;
+                node->gtHWIntrinsicId = (simdSize == 16) ? NI_Vector128_get_AllBitsSet : NI_Vector256_get_AllBitsSet;
                 return;
             }
         }
diff --git a/src/tests/JIT/HardwareIntrinsics/General/Regression/GitHub_47236/GitHub_47236.cs b/src/tests/JIT/HardwareIntrinsics/General/Regression/GitHub_47236/GitHub_47236.cs
new file mode 100644 (file)
index 0000000..6f18bcc
--- /dev/null
@@ -0,0 +1,175 @@
+// 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;
+
+public static class Program
+{
+    private static int s_returnCode = 100;
+
+    public static int Main(string[] args)
+    {
+        TestVector256();
+        TestVector128();
+        TestVector64();
+        return s_returnCode;
+    }
+
+    public static void TestVector256()
+    {
+        // Test get_Zero() optimization:
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>", Vector256.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1>", Vector256.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>", Vector256.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1>", Vector256.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0>", Vector256.Create(1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0>", Vector256.Create(0, 0, 0, 0, 0, 0, 0, 0).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 1>", Vector256.Create(0, 0, 0, 0, 0, 0, 0, 1).ToString());
+        Assert("<0, 0, 0, 0, 1, 1, 1, 1>", Vector256.Create(0, 0, 0, 0, 1, 1, 1, 1).ToString());
+        Assert("<0, 0, 0, 1, 1, 1, 1, 1>", Vector256.Create(0, 0, 0, 1, 1, 1, 1, 1).ToString());
+        Assert("<0, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(0, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 0, 0, 0, 0>", Vector256.Create(1, 1, 1, 1, 0, 0, 0, 0).ToString());
+        Assert("<0, 0, 0, 0>", Vector256.Create(0, 0, 0, 0).ToString());
+        Assert("<0, 0, 1, 1>", Vector256.Create(0, 0, 1, 1).ToString());
+        Assert("<0, 1, 1, 1>", Vector256.Create(0, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1>", Vector256.Create(1, 1, 1, 1).ToString());
+        Assert("<1, 1, 0, 0>", Vector256.Create(1, 1, 0, 0).ToString());
+
+        // Test get_AllBitSet() optimization:
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1>", Vector256.Create(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1>", Vector256.Create(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1>", Vector256.Create(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1>", Vector256.Create(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(-1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(-1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1>", Vector256.Create(1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1>", Vector256.Create(-1, -1, -1, -1, -1, -1, -1, -1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, 1>", Vector256.Create(-1, -1, -1, -1, -1, -1, -1, 1).ToString());
+        Assert("<-1, -1, -1, -1, 1, 1, 1, 1>", Vector256.Create(-1, -1, -1, -1, 1, 1, 1, 1).ToString());
+        Assert("<-1, -1, -1, 1, 1, 1, 1, 1>", Vector256.Create(-1, -1, -1, 1, 1, 1, 1, 1).ToString());
+        Assert("<-1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(-1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1>", Vector256.Create(1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, -1, -1, -1, -1>", Vector256.Create(1, 1, 1, 1, -1, -1, -1, -1).ToString());
+        Assert("<-1, -1, -1, -1>", Vector256.Create(-1, -1, -1, -1).ToString());
+        Assert("<-1, -1, 1, 1>", Vector256.Create(-1, -1, 1, 1).ToString());
+        Assert("<-1, 1, 1, 1>", Vector256.Create(-1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1>", Vector256.Create(1, 1, 1, 1).ToString());
+        Assert("<1, 1, -1, -1>", Vector256.Create(1, 1, -1, -1).ToString());
+    }
+
+    public static void TestVector128()
+    {
+        // Test get_Zero() optimization:
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0>", Vector128.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1>", Vector128.Create(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0>", Vector128.Create(1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0>", Vector128.Create(0, 0, 0, 0, 0, 0, 0, 0).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 1>", Vector128.Create(0, 0, 0, 0, 0, 0, 0, 1).ToString());
+        Assert("<0, 0, 0, 0, 1, 1, 1, 1>", Vector128.Create(0, 0, 0, 0, 1, 1, 1, 1).ToString());
+        Assert("<0, 0, 0, 1, 1, 1, 1, 1>", Vector128.Create(0, 0, 0, 1, 1, 1, 1, 1).ToString());
+        Assert("<0, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(0, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 0, 0, 0, 0>", Vector128.Create(1, 1, 1, 1, 0, 0, 0, 0).ToString());
+        Assert("<0, 0, 0, 0>", Vector128.Create(0, 0, 0, 0).ToString());
+        Assert("<0, 0, 1, 1>", Vector128.Create(0, 0, 1, 1).ToString());
+        Assert("<0, 1, 1, 1>", Vector128.Create(0, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1>", Vector128.Create(1, 1, 1, 1).ToString());
+        Assert("<1, 1, 0, 0>", Vector128.Create(1, 1, 0, 0).ToString());
+        Assert("<0, 0>", Vector128.Create(0, 0).ToString());
+        Assert("<0, 1>", Vector128.Create(0, 1).ToString());
+        Assert("<1, 1>", Vector128.Create(1, 1).ToString());
+        Assert("<1, 0>", Vector128.Create(1, 0).ToString());
+
+        // Test get_AllBitSet() optimization:
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1>", Vector128.Create(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1>", Vector128.Create(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(-1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(-1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1>", Vector128.Create(1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1>", Vector128.Create(-1, -1, -1, -1, -1, -1, -1, -1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, 1>", Vector128.Create(-1, -1, -1, -1, -1, -1, -1, 1).ToString());
+        Assert("<-1, -1, -1, -1, 1, 1, 1, 1>", Vector128.Create(-1, -1, -1, -1, 1, 1, 1, 1).ToString());
+        Assert("<-1, -1, -1, 1, 1, 1, 1, 1>", Vector128.Create(-1, -1, -1, 1, 1, 1, 1, 1).ToString());
+        Assert("<-1, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(-1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1>", Vector128.Create(1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, -1, -1, -1, -1>", Vector128.Create(1, 1, 1, 1, -1, -1, -1, -1).ToString());
+        Assert("<-1, -1, -1, -1>", Vector128.Create(-1, -1, -1, -1).ToString());
+        Assert("<-1, -1, 1, 1>", Vector128.Create(-1, -1, 1, 1).ToString());
+        Assert("<-1, 1, 1, 1>", Vector128.Create(-1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1>", Vector128.Create(1, 1, 1, 1).ToString());
+        Assert("<1, 1, -1, -1>", Vector128.Create(1, 1, -1, -1).ToString());
+        Assert("<-1, -1>", Vector128.Create(-1, -1).ToString());
+        Assert("<-1, 1>", Vector128.Create(-1, 1).ToString());
+        Assert("<1, -1>", Vector128.Create(1, -1).ToString());
+    }
+
+    public static void TestVector64()
+    {
+        // Test get_Zero() optimization:
+        Assert("<0, 0, 0, 0, 0, 0, 0, 0>", Vector64.Create(0, 0, 0, 0, 0, 0, 0, 0).ToString());
+        Assert("<0, 0, 0, 0, 0, 0, 0, 1>", Vector64.Create(0, 0, 0, 0, 0, 0, 0, 1).ToString());
+        Assert("<0, 0, 0, 0, 1, 1, 1, 1>", Vector64.Create(0, 0, 0, 0, 1, 1, 1, 1).ToString());
+        Assert("<0, 0, 0, 1, 1, 1, 1, 1>", Vector64.Create(0, 0, 0, 1, 1, 1, 1, 1).ToString());
+        Assert("<0, 1, 1, 1, 1, 1, 1, 1>", Vector64.Create(0, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1>", Vector64.Create(1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 0, 0, 0, 0>", Vector64.Create(1, 1, 1, 1, 0, 0, 0, 0).ToString());
+        Assert("<0, 0, 0, 0>", Vector64.Create(0, 0, 0, 0).ToString());
+        Assert("<0, 0, 1, 1>", Vector64.Create(0, 0, 1, 1).ToString());
+        Assert("<0, 1, 1, 1>", Vector64.Create(0, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1>", Vector64.Create(1, 1, 1, 1).ToString());
+        Assert("<1, 1, 0, 0>", Vector64.Create(1, 1, 0, 0).ToString());
+        Assert("<0, 0>", Vector64.Create(0, 0).ToString());
+        Assert("<0, 1>", Vector64.Create(0, 1).ToString());
+        Assert("<1, 1>", Vector64.Create(1, 1).ToString());
+        Assert("<1, 0>", Vector64.Create(1, 0).ToString());
+
+        // Test get_AllBitSet() optimization:
+        Assert("<-1, -1, -1, -1, -1, -1, -1, -1>", Vector64.Create(-1, -1, -1, -1, -1, -1, -1, -1).ToString());
+        Assert("<-1, -1, -1, -1, -1, -1, -1, 1>", Vector64.Create(-1, -1, -1, -1, -1, -1, -1, 1).ToString());
+        Assert("<-1, -1, -1, -1, 1, 1, 1, 1>", Vector64.Create(-1, -1, -1, -1, 1, 1, 1, 1).ToString());
+        Assert("<-1, -1, -1, 1, 1, 1, 1, 1>", Vector64.Create(-1, -1, -1, 1, 1, 1, 1, 1).ToString());
+        Assert("<-1, 1, 1, 1, 1, 1, 1, 1>", Vector64.Create(-1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, 1, 1, 1, 1>", Vector64.Create(1, 1, 1, 1, 1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1, -1, -1, -1, -1>", Vector64.Create(1, 1, 1, 1, -1, -1, -1, -1).ToString());
+        Assert("<-1, -1, -1, -1>", Vector64.Create(-1, -1, -1, -1).ToString());
+        Assert("<-1, -1, 1, 1>", Vector64.Create(-1, -1, 1, 1).ToString());
+        Assert("<-1, 1, 1, 1>", Vector64.Create(-1, 1, 1, 1).ToString());
+        Assert("<1, 1, 1, 1>", Vector64.Create(1, 1, 1, 1).ToString());
+        Assert("<1, 1, -1, -1>", Vector64.Create(1, 1, -1, -1).ToString());
+        Assert("<-1, -1>", Vector64.Create(-1, -1).ToString());
+        Assert("<-1, 1>", Vector64.Create(-1, 1).ToString());
+        Assert("<1, -1>", Vector64.Create(1, -1).ToString());
+    }
+
+    private static void Assert(string expected, string actual, [CallerLineNumber] int line = 0)
+    {
+        if (expected != actual)
+        {
+            s_returnCode++;
+            Console.WriteLine($"{expected} != {actual}, L{line}");
+        }
+    }
+}
diff --git a/src/tests/JIT/HardwareIntrinsics/General/Regression/GitHub_47236/GitHub_47236.csproj b/src/tests/JIT/HardwareIntrinsics/General/Regression/GitHub_47236/GitHub_47236.csproj
new file mode 100644 (file)
index 0000000..56a11eb
--- /dev/null
@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+  </PropertyGroup>
+  <PropertyGroup>
+    <DebugType>Embedded</DebugType>
+    <Optimize>True</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="GitHub_47236.cs" />
+  </ItemGroup>
+</Project>
index 052e883..d7a6bb9 100644 (file)
         <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/General/Regression/GitHub_43569/**">
             <Issue>https://github.com/dotnet/runtime/issues/43676</Issue>
         </ExcludeList>
+        <ExcludeList Include="$(XunitTestBinBase)/JIT/HardwareIntrinsics/General/Regression/GitHub_47236/**">
+            <Issue>https://github.com/dotnet/runtime/issues/43676</Issue>
+        </ExcludeList>
         <ExcludeList Include="$(XunitTestBinBase)/baseservices/TieredCompilation/BasicTestWithMcj/*">
             <Issue>Tests features specific to coreclr</Issue>
         </ExcludeList>