Skip to content

Commit

Permalink
Enable support for nint/nuint for Vector64/128/256<T> (#63329)
Browse files Browse the repository at this point in the history
* Enable support for nint/nuint for Vector64/128/256<T>

* Adding the additional Vector64/128/256<T> APIs required to support nint/nuint

* Removing the "NotSupported" tests for nint/nuint of Vector64/128/256<T>
  • Loading branch information
tannergooding committed Jan 4, 2022
1 parent 33731fc commit eed3a62
Show file tree
Hide file tree
Showing 277 changed files with 481 additions and 11,892 deletions.
6 changes: 0 additions & 6 deletions src/coreclr/jit/hwintrinsic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -596,12 +596,6 @@ static bool isSupportedBaseType(NamedIntrinsic intrinsic, CorInfoType baseJitTyp
return false;
}

if ((baseJitType == CORINFO_TYPE_NATIVEINT) || (baseJitType == CORINFO_TYPE_NATIVEUINT))
{
// We don't want to support the general purpose helpers for nint/nuint until after they go through API review.
return false;
}

var_types baseType = JitType2PreciseVarType(baseJitType);

// We don't actually check the intrinsic outside of the false case as we expect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,25 @@ public static Vector128<int> AsInt32<T>(this Vector128<T> vector)
public static Vector128<long> AsInt64<T>(this Vector128<T> vector)
where T : struct => vector.As<T, long>();

/// <summary>Reinterprets a <see cref="Vector128{T}" /> as a new <see cref="Vector128{IntPtr}" />.</summary>
/// <typeparam name="T">The type of the input vector.</typeparam>
/// <param name="vector">The vector to reinterpret.</param>
/// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector128{IntPtr}" />.</returns>
/// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
[Intrinsic]
public static Vector128<nint> AsNInt<T>(this Vector128<T> vector)
where T : struct => vector.As<T, nint>();

/// <summary>Reinterprets a <see cref="Vector128{T}" /> as a new <see cref="Vector128{UIntPtr}" />.</summary>
/// <typeparam name="T">The type of the input vector.</typeparam>
/// <param name="vector">The vector to reinterpret.</param>
/// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector128{UIntPtr}" />.</returns>
/// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
[Intrinsic]
[CLSCompliant(false)]
public static Vector128<nuint> AsNUInt<T>(this Vector128<T> vector)
where T : struct => vector.As<T, nuint>();

/// <summary>Reinterprets a <see cref="Vector128{T}" /> as a new <see cref="Vector128{SByte}" />.</summary>
/// <typeparam name="T">The type of the input vector.</typeparam>
/// <param name="vector">The vector to reinterpret.</param>
Expand Down Expand Up @@ -864,6 +883,59 @@ static Vector128<long> SoftwareFallback(long value)
}
}

/// <summary>Creates a new <see cref="Vector128{IntPtr}" /> instance with all elements initialized to the specified value.</summary>
/// <param name="value">The value that all elements will be initialized to.</param>
/// <returns>A new <see cref="Vector128{IntPtr}" /> with all elements initialized to <paramref name="value" />.</returns>
[Intrinsic]
public static unsafe Vector128<nint> Create(nint value)
{
if (Sse2.IsSupported || AdvSimd.IsSupported)
{
return Create(value);
}

return SoftwareFallback(value);

static Vector128<nint> SoftwareFallback(nint value)
{
if (Environment.Is64BitProcess)
{
return Create((long)value).AsNInt();
}
else
{
return Create((int)value).AsNInt();
}
}
}

/// <summary>Creates a new <see cref="Vector128{UIntPtr}" /> instance with all elements initialized to the specified value.</summary>
/// <param name="value">The value that all elements will be initialized to.</param>
/// <returns>A new <see cref="Vector128{UIntPtr}" /> with all elements initialized to <paramref name="value" />.</returns>
[Intrinsic]
[CLSCompliant(false)]
public static unsafe Vector128<nuint> Create(nuint value)
{
if (Sse2.IsSupported || AdvSimd.IsSupported)
{
return Create(value);
}

return SoftwareFallback(value);

static Vector128<nuint> SoftwareFallback(nuint value)
{
if (Environment.Is64BitProcess)
{
return Create((ulong)value).AsNUInt();
}
else
{
return Create((uint)value).AsNUInt();
}
}
}

/// <summary>Creates a new <see cref="Vector128{SByte}" /> instance with all elements initialized to the specified value.</summary>
/// <param name="value">The value that all elements will be initialized to.</param>
/// <remarks>On x86, this method corresponds to __m128i _mm_set1_epi8</remarks>
Expand Down Expand Up @@ -1817,6 +1889,7 @@ static Vector128<int> SoftwareFallback(int value)
/// <summary>Creates a new <see cref="Vector128{Int64}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector128{Int64}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Vector128<long> CreateScalar(long value)
{
if (AdvSimd.IsSupported)
Expand All @@ -1839,6 +1912,39 @@ static Vector128<long> SoftwareFallback(long value)
}
}

/// <summary>Creates a new <see cref="Vector128{IntPtr}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector128{IntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements initialized to zero.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Vector128<nint> CreateScalar(nint value)
{
if (Environment.Is64BitProcess)
{
return CreateScalar((long)value).AsNInt();
}
else
{
return CreateScalar((int)value).AsNInt();
}
}

/// <summary>Creates a new <see cref="Vector128{UIntPtr}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector128{UIntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements initialized to zero.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static unsafe Vector128<nuint> CreateScalar(nuint value)
{
if (Environment.Is64BitProcess)
{
return CreateScalar((ulong)value).AsNUInt();
}
else
{
return CreateScalar((uint)value).AsNUInt();
}
}

/// <summary>Creates a new <see cref="Vector128{SByte}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector128{SByte}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
Expand Down Expand Up @@ -2047,6 +2153,39 @@ public static unsafe Vector128<long> CreateScalarUnsafe(long value)
return Unsafe.AsRef<Vector128<long>>(pResult);
}

/// <summary>Creates a new <see cref="Vector128{IntPtr}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector128{IntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements left uninitialized.</returns>
[Intrinsic]
public static unsafe Vector128<nint> CreateScalarUnsafe(nint value)
{
if (Environment.Is64BitProcess)
{
return CreateScalarUnsafe((long)value).AsNInt();
}
else
{
return CreateScalarUnsafe((int)value).AsNInt();
}
}

/// <summary>Creates a new <see cref="Vector128{UIntPtr}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector128{UIntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements left uninitialized.</returns>
[Intrinsic]
[CLSCompliant(false)]
public static unsafe Vector128<nuint> CreateScalarUnsafe(nuint value)
{
if (Environment.Is64BitProcess)
{
return CreateScalarUnsafe((ulong)value).AsNUInt();
}
else
{
return CreateScalarUnsafe((uint)value).AsNUInt();
}
}

/// <summary>Creates a new <see cref="Vector128{SByte}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector128{SByte}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,25 @@ public static Vector256<int> AsInt32<T>(this Vector256<T> vector)
public static Vector256<long> AsInt64<T>(this Vector256<T> vector)
where T : struct => vector.As<T, long>();

/// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{IntPtr}" />.</summary>
/// <typeparam name="T">The type of the input vector.</typeparam>
/// <param name="vector">The vector to reinterpret.</param>
/// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{IntPtr}" />.</returns>
/// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
[Intrinsic]
public static Vector256<nint> AsNInt<T>(this Vector256<T> vector)
where T : struct => vector.As<T, nint>();

/// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{UIntPtr}" />.</summary>
/// <typeparam name="T">The type of the input vector.</typeparam>
/// <param name="vector">The vector to reinterpret.</param>
/// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{UIntPtr}" />.</returns>
/// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
[Intrinsic]
[CLSCompliant(false)]
public static Vector256<nuint> AsNUInt<T>(this Vector256<T> vector)
where T : struct => vector.As<T, nuint>();

/// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{SByte}" />.</summary>
/// <typeparam name="T">The type of the input vector.</typeparam>
/// <param name="vector">The vector to reinterpret.</param>
Expand Down Expand Up @@ -842,6 +861,59 @@ static Vector256<long> SoftwareFallback(long value)
}
}

/// <summary>Creates a new <see cref="Vector256{IntPtr}" /> instance with all elements initialized to the specified value.</summary>
/// <param name="value">The value that all elements will be initialized to.</param>
/// <returns>A new <see cref="Vector256{IntPtr}" /> with all elements initialized to <paramref name="value" />.</returns>
[Intrinsic]
public static unsafe Vector256<nint> Create(nint value)
{
if (Avx.IsSupported)
{
return Create(value);
}

return SoftwareFallback(value);

static Vector256<nint> SoftwareFallback(nint value)
{
if (Environment.Is64BitProcess)
{
return Create((long)value).AsNInt();
}
else
{
return Create((int)value).AsNInt();
}
}
}

/// <summary>Creates a new <see cref="Vector256{UIntPtr}" /> instance with all elements initialized to the specified value.</summary>
/// <param name="value">The value that all elements will be initialized to.</param>
/// <returns>A new <see cref="Vector256{UIntPtr}" /> with all elements initialized to <paramref name="value" />.</returns>
[Intrinsic]
[CLSCompliant(false)]
public static unsafe Vector256<nuint> Create(nuint value)
{
if (Avx.IsSupported)
{
return Create(value);
}

return SoftwareFallback(value);

static Vector256<nuint> SoftwareFallback(nuint value)
{
if (Environment.Is64BitProcess)
{
return Create((ulong)value).AsNUInt();
}
else
{
return Create((uint)value).AsNUInt();
}
}
}

/// <summary>Creates a new <see cref="Vector256{SByte}" /> instance with all elements initialized to the specified value.</summary>
/// <param name="value">The value that all elements will be initialized to.</param>
/// <remarks>On x86, this method corresponds to __m256i _mm256_set1_epi8</remarks>
Expand Down Expand Up @@ -1967,6 +2039,59 @@ static Vector256<long> SoftwareFallback(long value)
}
}

/// <summary>Creates a new <see cref="Vector256{IntPtr}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector256{IntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements initialized to zero.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Vector256<nint> CreateScalar(nint value)
{
if (Avx.IsSupported)
{
return Create(value);
}

return SoftwareFallback(value);

static Vector256<nint> SoftwareFallback(nint value)
{
if (Environment.Is64BitProcess)
{
return CreateScalar((long)value).AsNInt();
}
else
{
return CreateScalar((int)value).AsNInt();
}
}
}

/// <summary>Creates a new <see cref="Vector256{UIntPtr}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector256{UIntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements initialized to zero.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[CLSCompliant(false)]
public static unsafe Vector256<nuint> CreateScalar(nuint value)
{
if (Avx.IsSupported)
{
return Create(value);
}

return SoftwareFallback(value);

static Vector256<nuint> SoftwareFallback(nuint value)
{
if (Environment.Is64BitProcess)
{
return CreateScalar((ulong)value).AsNUInt();
}
else
{
return CreateScalar((uint)value).AsNUInt();
}
}
}

/// <summary>Creates a new <see cref="Vector256{SByte}" /> instance with the first element initialized to the specified value and the remaining elements initialized to zero.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector256{SByte}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements initialized to zero.</returns>
Expand Down Expand Up @@ -2146,6 +2271,39 @@ public static unsafe Vector256<long> CreateScalarUnsafe(long value)
return Unsafe.AsRef<Vector256<long>>(pResult);
}

/// <summary>Creates a new <see cref="Vector256{IntPtr}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector256{IntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements left uninitialized.</returns>
[Intrinsic]
public static unsafe Vector256<nint> CreateScalarUnsafe(nint value)
{
if (Environment.Is64BitProcess)
{
return CreateScalarUnsafe((long)value).AsNInt();
}
else
{
return CreateScalarUnsafe((int)value).AsNInt();
}
}

/// <summary>Creates a new <see cref="Vector256{UIntPtr}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector256{UIntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements left uninitialized.</returns>
[Intrinsic]
[CLSCompliant(false)]
public static unsafe Vector256<nuint> CreateScalarUnsafe(nuint value)
{
if (Environment.Is64BitProcess)
{
return CreateScalarUnsafe((ulong)value).AsNUInt();
}
else
{
return CreateScalarUnsafe((uint)value).AsNUInt();
}
}

/// <summary>Creates a new <see cref="Vector256{SByte}" /> instance with the first element initialized to the specified value and the remaining elements left uninitialized.</summary>
/// <param name="value">The value that element 0 will be initialized to.</param>
/// <returns>A new <see cref="Vector256{SByte}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>
Expand Down
Loading

0 comments on commit eed3a62

Please sign in to comment.