From 552ed75969a642284b5d7c4cd08e6f1e78178ff3 Mon Sep 17 00:00:00 2001 From: Fei Peng Date: Tue, 27 Feb 2018 22:18:06 -0800 Subject: [PATCH] Fix StaticCast with NotSupportedException --- src/jit/hwintrinsicxarch.cpp | 14 ++----- src/jit/simd.cpp | 6 ++- .../src/System/Runtime/Intrinsics/X86/Avx.cs | 14 ------- .../src/System/Runtime/Intrinsics/X86/Avx2.cs | 2 - .../src/System/Runtime/Intrinsics/X86/Sse.cs | 2 - .../src/System/Runtime/Intrinsics/X86/Sse2.cs | 1 - .../JIT/HardwareIntrinsics/X86/Sse/StaticCast.cs | 44 +++++++++++++++++++++- 7 files changed, 51 insertions(+), 32 deletions(-) diff --git a/src/jit/hwintrinsicxarch.cpp b/src/jit/hwintrinsicxarch.cpp index 3b6ef76..612bc7c 100644 --- a/src/jit/hwintrinsicxarch.cpp +++ b/src/jit/hwintrinsicxarch.cpp @@ -426,7 +426,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, unsigned int sizeBytes; baseType = getBaseTypeAndSizeOfSIMDType(sig->retTypeSigClass, &sizeBytes); retType = getSIMDTypeForSize(sizeBytes); - assert(sizeBytes != 0 && baseType != TYP_UNKNOWN); + assert(sizeBytes != 0); } // This intrinsic is supported if @@ -460,25 +460,19 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, if ((flags & (HW_Flag_OneTypeGeneric | HW_Flag_TwoTypeGeneric)) != 0) { - assert(baseType != TYP_UNKNOWN); - // When the type argument is not a numeric type (and we are not being forced to expand), we need to - // return nullptr so a GT_CALL to the intrinsic method is emitted that will throw NotSupportedException if (!varTypeIsArithmetic(baseType)) { - assert(!mustExpand); - return nullptr; + return impUnsupportedHWIntrinsic(CORINFO_HELP_THROW_TYPE_NOT_SUPPORTED, method, sig, mustExpand); } if ((flags & HW_Flag_TwoTypeGeneric) != 0) { // StaticCast has two type parameters. - assert(!mustExpand); assert(numArgs == 1); var_types srcType = getBaseTypeOfSIMDType(info.compCompHnd->getArgClass(sig, sig->args)); - assert(srcType != TYP_UNKNOWN); if (!varTypeIsArithmetic(srcType)) { - return nullptr; + return impUnsupportedHWIntrinsic(CORINFO_HELP_THROW_TYPE_NOT_SUPPORTED, method, sig, mustExpand); } } } @@ -493,7 +487,7 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, // table-driven importer of simple intrinsics if (impIsTableDrivenHWIntrinsic(category, flags)) { - if (!varTypeIsSIMD(retType) || (flags & HW_Flag_BaseTypeFromArg)) + if (!varTypeIsSIMD(retType) || ((flags & HW_Flag_BaseTypeFromArg) != 0)) { if (retType != TYP_VOID) { diff --git a/src/jit/simd.cpp b/src/jit/simd.cpp index 62bed5f..56a1e9d 100644 --- a/src/jit/simd.cpp +++ b/src/jit/simd.cpp @@ -707,9 +707,13 @@ var_types Compiler::getBaseTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeHnd, u } } - if (simdBaseType != TYP_UNKNOWN && sizeBytes != nullptr) + if (sizeBytes != nullptr) { *sizeBytes = size; + } + + if (simdBaseType != TYP_UNKNOWN) + { setUsesSIMDTypes(true); } } diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs index 48ad6cb..37487df 100644 --- a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs +++ b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs @@ -285,7 +285,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector128 ExtractVector128(Vector256 value, byte index) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return ExtractVector128(value, index); } @@ -350,7 +349,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector256 ExtendToVector256(Vector128 value) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return ExtendToVector256(value); } @@ -375,7 +373,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector128 GetLowerHalf(Vector256 value) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return GetLowerHalf(value); } @@ -452,7 +449,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector256 Insert(Vector256 value, Vector128 data, byte index) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return Insert(value, data, index); } @@ -781,7 +777,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector256 Permute2x128(Vector256 left, Vector256 right, byte control) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return Permute2x128(left, right, control); } @@ -937,7 +932,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector256 SetAllVector256(T value) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return SetAllVector256(value); } @@ -951,7 +945,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector256 SetHighLow(Vector128 hi, Vector128 lo) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return SetHighLow(hi, lo); } @@ -965,7 +958,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector256 SetZeroVector256() where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return SetZeroVector256(); } @@ -1007,8 +999,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector256 StaticCast(Vector256 value) where T : struct where U : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return StaticCast(value); } @@ -1197,7 +1187,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static bool TestC(Vector256 left, Vector256 right) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return TestC(left, right); } @@ -1222,7 +1211,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static bool TestNotZAndNotC(Vector256 left, Vector256 right) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return TestNotZAndNotC(left, right); } @@ -1247,7 +1235,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static bool TestZ(Vector256 left, Vector256 right) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return TestZ(left, right); } @@ -1305,7 +1292,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector256 ZeroExtendToVector256(Vector128 value) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return ZeroExtendToVector256(value); } } diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx2.cs b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx2.cs index 0745fac..0b0663b 100644 --- a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx2.cs +++ b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx2.cs @@ -250,7 +250,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector128 BroadcastScalarToVector128(Vector128 value) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return BroadcastScalarToVector128(value); } @@ -270,7 +269,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector256 BroadcastScalarToVector256(Vector128 value) where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return BroadcastScalarToVector256(value); } diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse.cs b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse.cs index 8b089c8..fa789eb 100644 --- a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse.cs +++ b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse.cs @@ -503,8 +503,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector128 StaticCast(Vector128 value) where T : struct where U : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return StaticCast(value); } diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse2.cs b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse2.cs index 50eb8ef..5d1ddf3 100644 --- a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse2.cs +++ b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Sse2.cs @@ -1073,7 +1073,6 @@ namespace System.Runtime.Intrinsics.X86 /// public static Vector128 SetZeroVector128() where T : struct { - ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType(); return SetZeroVector128(); } diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/StaticCast.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/StaticCast.cs index 3c541f8..707b9b1 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/StaticCast.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/StaticCast.cs @@ -11,6 +11,13 @@ using System.Runtime.Intrinsics; namespace IntelHardwareIntrinsicTest { + // that it is intentionally designed to be a struct type that meets + // the generic constraint but is not supported by any intrinsics + struct Num + { + public int a; + } + class Program { const int Pass = 100; @@ -39,12 +46,45 @@ namespace IntelHardwareIntrinsicTest Console.WriteLine(); testResult = Fail; } - } - } + // the successful path is the one that catches the exception, so that does nothing, + // it is the fall-through path that's the error path + try + { + var v = Sse.StaticCast(vf1); + Unsafe.Write(floatTable.outArrayPtr, v); + Console.WriteLine("SSE StaticCast failed on target type test:"); + testResult = Fail; + } + catch (System.NotSupportedException) + { + } + // the successful path is the one that catches the exception, so that does nothing, + // it is the fall-through path that's the error path + try + { + var v = TestSrcType(); + Unsafe.Write(floatTable.outArrayPtr, v); + Console.WriteLine("SSE StaticCast failed on source type test:"); + testResult = Fail; + } + catch (System.NotSupportedException) + { + } + } + } + return testResult; } + + [MethodImpl(MethodImplOptions.NoInlining)] + static Vector128 TestSrcType() + { + Vector128 v1 = new Vector128(); + Vector128 v2 = new Vector128(); + return Sse2.Add(Sse.StaticCast(v1), Sse.StaticCast(v2)); + } public unsafe struct TestTable : IDisposable where T : struct where U : struct { -- 2.7.4