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
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<T, U> 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);
}
}
}
// 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)
{
}
}
- if (simdBaseType != TYP_UNKNOWN && sizeBytes != nullptr)
+ if (sizeBytes != nullptr)
{
*sizeBytes = size;
+ }
+
+ if (simdBaseType != TYP_UNKNOWN)
+ {
setUsesSIMDTypes(true);
}
}
/// </summary>
public static Vector128<T> ExtractVector128<T>(Vector256<T> value, byte index) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return ExtractVector128<T>(value, index);
}
/// </summary>
public static Vector256<T> ExtendToVector256<T>(Vector128<T> value) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return ExtendToVector256<T>(value);
}
/// </summary>
public static Vector128<T> GetLowerHalf<T>(Vector256<T> value) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return GetLowerHalf<T>(value);
}
/// </summary>
public static Vector256<T> Insert<T>(Vector256<T> value, Vector128<T> data, byte index) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return Insert<T>(value, data, index);
}
/// </summary>
public static Vector256<T> Permute2x128<T>(Vector256<T> left, Vector256<T> right, byte control) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return Permute2x128<T>(left, right, control);
}
/// </summary>
public static Vector256<T> SetAllVector256<T>(T value) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return SetAllVector256<T>(value);
}
/// </summary>
public static Vector256<T> SetHighLow<T>(Vector128<T> hi, Vector128<T> lo) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return SetHighLow<T>(hi, lo);
}
/// </summary>
public static Vector256<T> SetZeroVector256<T>() where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return SetZeroVector256<T>();
}
/// </summary>
public static Vector256<U> StaticCast<T, U>(Vector256<T> value) where T : struct where U : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return StaticCast<T, U>(value);
}
/// </summary>
public static bool TestC<T>(Vector256<T> left, Vector256<T> right) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return TestC<T>(left, right);
}
/// </summary>
public static bool TestNotZAndNotC<T>(Vector256<T> left, Vector256<T> right) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return TestNotZAndNotC<T>(left, right);
}
/// </summary>
public static bool TestZ<T>(Vector256<T> left, Vector256<T> right) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return TestZ<T>(left, right);
}
/// </summary>
public static Vector256<T> ZeroExtendToVector256<T>(Vector128<T> value) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return ZeroExtendToVector256<T>(value);
}
}
/// </summary>
public static Vector128<T> BroadcastScalarToVector128<T>(Vector128<T> value) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return BroadcastScalarToVector128<T>(value);
}
/// </summary>
public static Vector256<T> BroadcastScalarToVector256<T>(Vector128<T> value) where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return BroadcastScalarToVector256<T>(value);
}
/// </summary>
public static Vector128<U> StaticCast<T, U>(Vector128<T> value) where T : struct where U : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<U>();
return StaticCast<T, U>(value);
}
/// </summary>
public static Vector128<T> SetZeroVector128<T>() where T : struct
{
- ThrowHelper.ThrowNotSupportedExceptionIfNonNumericType<T>();
return SetZeroVector128<T>();
}
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;
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<float, Num>(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<int> TestSrcType()
+ {
+ Vector128<Num> v1 = new Vector128<Num>();
+ Vector128<Num> v2 = new Vector128<Num>();
+ return Sse2.Add(Sse.StaticCast<Num, int>(v1), Sse.StaticCast<Num, int>(v2));
+ }
public unsafe struct TestTable<T, U> : IDisposable where T : struct where U : struct
{