Fix SIMD intrinsics handling in crossgen2 (dotnet/coreclr#27853)
authorJan Vorlicek <janvorli@microsoft.com>
Wed, 13 Nov 2019 19:40:58 +0000 (20:40 +0100)
committerGitHub <noreply@github.com>
Wed, 13 Nov 2019 19:40:58 +0000 (20:40 +0100)
* Fix SIMD intrinsics handling in crossgen2

Crossgen2 was compiling methods that call SIMD intrinsics
(System.Numerics.Vector<T>). This is not correct, as the size of the
vector is a runtime specific detail - e.g. when running on devices
without SSE2 support, the size is 4 and when running on devices with
SSE2 support, the size is 8.
This fixes runtime errors in 6 coreclr pri 0 tests.

* Reflect PR feedback

Create a IsVectorOfT method and use it at all places where we were
previously checking the namespace and type name of Vector<T>

Commit migrated from https://github.com/dotnet/coreclr/commit/0f9814cc4e25ee4060d8f3ae2305210aef94f1bc

src/coreclr/src/tools/crossgen2/Common/Compiler/VectorFieldLayoutAlgorithm.cs
src/coreclr/src/tools/crossgen2/Common/JitInterface/CorInfoImpl.cs
src/coreclr/src/tools/crossgen2/Common/JitInterface/SystemVStructClassificator.cs
src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs

index 981eef3..f52f18c 100644 (file)
@@ -106,5 +106,10 @@ namespace ILCompiler
                 type.Name == "Vector128`1" ||
                 type.Name == "Vector256`1");
         }
+
+        public static bool IsVectorOfTType(DefType type)
+        {
+            return type.IsIntrinsic && type.Namespace == "System.Numerics" && type.Name == "Vector`1";
+        }
     }
 }
index 0bd121e..c8aa989 100644 (file)
@@ -697,6 +697,15 @@ namespace Internal.JitInterface
                 result |= CorInfoFlag.CORINFO_FLG_FINAL;
             }
 
+#if READYTORUN
+            // Check for SIMD intrinsics
+            DefType owningDefType = method.OwningType as DefType;
+            if (owningDefType != null && VectorFieldLayoutAlgorithm.IsVectorOfTType(owningDefType))
+            {
+                throw new RequiresRuntimeJitException("This function is using SIMD intrinsics, their size is machine specific");
+            }
+#endif
+
             // Check for hardware intrinsics
             if (HardwareIntrinsicHelpers.IsHardwareIntrinsic(method))
             {
index 9ae4e7c..fe7f13d 100644 (file)
@@ -4,6 +4,7 @@
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
+using ILCompiler;
 using Internal.TypeSystem;
 
 namespace Internal.JitInterface
@@ -261,16 +262,8 @@ namespace Internal.JitInterface
                 InstantiatedType instantiatedType = typeDesc as InstantiatedType;
                 if (instantiatedType != null)
                 {
-                    string typeName = instantiatedType.Name;
-                    string namespaceName = instantiatedType.Namespace;
-
-                    if (typeName == "Vector256`1" || typeName == "Vector128`1" || typeName == "Vector64`1")
-                    {
-                        Debug.Assert(namespaceName == "System.Runtime.Intrinsics");
-                        return false;
-                    }
-
-                    if ((typeName ==  "Vector`1") && (namespaceName == "System.Numerics"))
+                    if (VectorFieldLayoutAlgorithm.IsVectorType(instantiatedType) ||
+                        VectorFieldLayoutAlgorithm.IsVectorOfTType(instantiatedType))
                     {
                         return false;
                     }
index 5ffa4e5..d01996f 100644 (file)
@@ -45,7 +45,7 @@ namespace ILCompiler
                 throw new NotImplementedException();
             else if (type.IsRuntimeDeterminedType)
                 throw new NotImplementedException();
-            else if (type.IsIntrinsic && (type.Name == "Vector`1") && (type.Namespace == "System.Numerics"))
+            else if (VectorIntrinsicFieldLayoutAlgorithm.IsVectorOfTType(type))
             {
                 return _vectorFieldLayoutAlgorithm;
             }