Skip to content

Commit eed3a62

Browse files
Enable support for nint/nuint for Vector64/128/256<T> (#63329)
* 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>
1 parent 33731fc commit eed3a62

File tree

277 files changed

+481
-11892
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

277 files changed

+481
-11892
lines changed

src/coreclr/jit/hwintrinsic.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -596,12 +596,6 @@ static bool isSupportedBaseType(NamedIntrinsic intrinsic, CorInfoType baseJitTyp
596596
return false;
597597
}
598598

599-
if ((baseJitType == CORINFO_TYPE_NATIVEINT) || (baseJitType == CORINFO_TYPE_NATIVEUINT))
600-
{
601-
// We don't want to support the general purpose helpers for nint/nuint until after they go through API review.
602-
return false;
603-
}
604-
605599
var_types baseType = JitType2PreciseVarType(baseJitType);
606600

607601
// We don't actually check the intrinsic outside of the false case as we expect

src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,25 @@ public static Vector128<int> AsInt32<T>(this Vector128<T> vector)
170170
public static Vector128<long> AsInt64<T>(this Vector128<T> vector)
171171
where T : struct => vector.As<T, long>();
172172

173+
/// <summary>Reinterprets a <see cref="Vector128{T}" /> as a new <see cref="Vector128{IntPtr}" />.</summary>
174+
/// <typeparam name="T">The type of the input vector.</typeparam>
175+
/// <param name="vector">The vector to reinterpret.</param>
176+
/// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector128{IntPtr}" />.</returns>
177+
/// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
178+
[Intrinsic]
179+
public static Vector128<nint> AsNInt<T>(this Vector128<T> vector)
180+
where T : struct => vector.As<T, nint>();
181+
182+
/// <summary>Reinterprets a <see cref="Vector128{T}" /> as a new <see cref="Vector128{UIntPtr}" />.</summary>
183+
/// <typeparam name="T">The type of the input vector.</typeparam>
184+
/// <param name="vector">The vector to reinterpret.</param>
185+
/// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector128{UIntPtr}" />.</returns>
186+
/// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
187+
[Intrinsic]
188+
[CLSCompliant(false)]
189+
public static Vector128<nuint> AsNUInt<T>(this Vector128<T> vector)
190+
where T : struct => vector.As<T, nuint>();
191+
173192
/// <summary>Reinterprets a <see cref="Vector128{T}" /> as a new <see cref="Vector128{SByte}" />.</summary>
174193
/// <typeparam name="T">The type of the input vector.</typeparam>
175194
/// <param name="vector">The vector to reinterpret.</param>
@@ -864,6 +883,59 @@ static Vector128<long> SoftwareFallback(long value)
864883
}
865884
}
866885

886+
/// <summary>Creates a new <see cref="Vector128{IntPtr}" /> instance with all elements initialized to the specified value.</summary>
887+
/// <param name="value">The value that all elements will be initialized to.</param>
888+
/// <returns>A new <see cref="Vector128{IntPtr}" /> with all elements initialized to <paramref name="value" />.</returns>
889+
[Intrinsic]
890+
public static unsafe Vector128<nint> Create(nint value)
891+
{
892+
if (Sse2.IsSupported || AdvSimd.IsSupported)
893+
{
894+
return Create(value);
895+
}
896+
897+
return SoftwareFallback(value);
898+
899+
static Vector128<nint> SoftwareFallback(nint value)
900+
{
901+
if (Environment.Is64BitProcess)
902+
{
903+
return Create((long)value).AsNInt();
904+
}
905+
else
906+
{
907+
return Create((int)value).AsNInt();
908+
}
909+
}
910+
}
911+
912+
/// <summary>Creates a new <see cref="Vector128{UIntPtr}" /> instance with all elements initialized to the specified value.</summary>
913+
/// <param name="value">The value that all elements will be initialized to.</param>
914+
/// <returns>A new <see cref="Vector128{UIntPtr}" /> with all elements initialized to <paramref name="value" />.</returns>
915+
[Intrinsic]
916+
[CLSCompliant(false)]
917+
public static unsafe Vector128<nuint> Create(nuint value)
918+
{
919+
if (Sse2.IsSupported || AdvSimd.IsSupported)
920+
{
921+
return Create(value);
922+
}
923+
924+
return SoftwareFallback(value);
925+
926+
static Vector128<nuint> SoftwareFallback(nuint value)
927+
{
928+
if (Environment.Is64BitProcess)
929+
{
930+
return Create((ulong)value).AsNUInt();
931+
}
932+
else
933+
{
934+
return Create((uint)value).AsNUInt();
935+
}
936+
}
937+
}
938+
867939
/// <summary>Creates a new <see cref="Vector128{SByte}" /> instance with all elements initialized to the specified value.</summary>
868940
/// <param name="value">The value that all elements will be initialized to.</param>
869941
/// <remarks>On x86, this method corresponds to __m128i _mm_set1_epi8</remarks>
@@ -1817,6 +1889,7 @@ static Vector128<int> SoftwareFallback(int value)
18171889
/// <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>
18181890
/// <param name="value">The value that element 0 will be initialized to.</param>
18191891
/// <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>
1892+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
18201893
public static unsafe Vector128<long> CreateScalar(long value)
18211894
{
18221895
if (AdvSimd.IsSupported)
@@ -1839,6 +1912,39 @@ static Vector128<long> SoftwareFallback(long value)
18391912
}
18401913
}
18411914

1915+
/// <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>
1916+
/// <param name="value">The value that element 0 will be initialized to.</param>
1917+
/// <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>
1918+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1919+
public static unsafe Vector128<nint> CreateScalar(nint value)
1920+
{
1921+
if (Environment.Is64BitProcess)
1922+
{
1923+
return CreateScalar((long)value).AsNInt();
1924+
}
1925+
else
1926+
{
1927+
return CreateScalar((int)value).AsNInt();
1928+
}
1929+
}
1930+
1931+
/// <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>
1932+
/// <param name="value">The value that element 0 will be initialized to.</param>
1933+
/// <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>
1934+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1935+
[CLSCompliant(false)]
1936+
public static unsafe Vector128<nuint> CreateScalar(nuint value)
1937+
{
1938+
if (Environment.Is64BitProcess)
1939+
{
1940+
return CreateScalar((ulong)value).AsNUInt();
1941+
}
1942+
else
1943+
{
1944+
return CreateScalar((uint)value).AsNUInt();
1945+
}
1946+
}
1947+
18421948
/// <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>
18431949
/// <param name="value">The value that element 0 will be initialized to.</param>
18441950
/// <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>
@@ -2047,6 +2153,39 @@ public static unsafe Vector128<long> CreateScalarUnsafe(long value)
20472153
return Unsafe.AsRef<Vector128<long>>(pResult);
20482154
}
20492155

2156+
/// <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>
2157+
/// <param name="value">The value that element 0 will be initialized to.</param>
2158+
/// <returns>A new <see cref="Vector128{IntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements left uninitialized.</returns>
2159+
[Intrinsic]
2160+
public static unsafe Vector128<nint> CreateScalarUnsafe(nint value)
2161+
{
2162+
if (Environment.Is64BitProcess)
2163+
{
2164+
return CreateScalarUnsafe((long)value).AsNInt();
2165+
}
2166+
else
2167+
{
2168+
return CreateScalarUnsafe((int)value).AsNInt();
2169+
}
2170+
}
2171+
2172+
/// <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>
2173+
/// <param name="value">The value that element 0 will be initialized to.</param>
2174+
/// <returns>A new <see cref="Vector128{UIntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements left uninitialized.</returns>
2175+
[Intrinsic]
2176+
[CLSCompliant(false)]
2177+
public static unsafe Vector128<nuint> CreateScalarUnsafe(nuint value)
2178+
{
2179+
if (Environment.Is64BitProcess)
2180+
{
2181+
return CreateScalarUnsafe((ulong)value).AsNUInt();
2182+
}
2183+
else
2184+
{
2185+
return CreateScalarUnsafe((uint)value).AsNUInt();
2186+
}
2187+
}
2188+
20502189
/// <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>
20512190
/// <param name="value">The value that element 0 will be initialized to.</param>
20522191
/// <returns>A new <see cref="Vector128{SByte}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>

src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,25 @@ public static Vector256<int> AsInt32<T>(this Vector256<T> vector)
169169
public static Vector256<long> AsInt64<T>(this Vector256<T> vector)
170170
where T : struct => vector.As<T, long>();
171171

172+
/// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{IntPtr}" />.</summary>
173+
/// <typeparam name="T">The type of the input vector.</typeparam>
174+
/// <param name="vector">The vector to reinterpret.</param>
175+
/// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{IntPtr}" />.</returns>
176+
/// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
177+
[Intrinsic]
178+
public static Vector256<nint> AsNInt<T>(this Vector256<T> vector)
179+
where T : struct => vector.As<T, nint>();
180+
181+
/// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{UIntPtr}" />.</summary>
182+
/// <typeparam name="T">The type of the input vector.</typeparam>
183+
/// <param name="vector">The vector to reinterpret.</param>
184+
/// <returns><paramref name="vector" /> reinterpreted as a new <see cref="Vector256{UIntPtr}" />.</returns>
185+
/// <exception cref="NotSupportedException">The type of <paramref name="vector" /> (<typeparamref name="T" />) is not supported.</exception>
186+
[Intrinsic]
187+
[CLSCompliant(false)]
188+
public static Vector256<nuint> AsNUInt<T>(this Vector256<T> vector)
189+
where T : struct => vector.As<T, nuint>();
190+
172191
/// <summary>Reinterprets a <see cref="Vector256{T}" /> as a new <see cref="Vector256{SByte}" />.</summary>
173192
/// <typeparam name="T">The type of the input vector.</typeparam>
174193
/// <param name="vector">The vector to reinterpret.</param>
@@ -842,6 +861,59 @@ static Vector256<long> SoftwareFallback(long value)
842861
}
843862
}
844863

864+
/// <summary>Creates a new <see cref="Vector256{IntPtr}" /> instance with all elements initialized to the specified value.</summary>
865+
/// <param name="value">The value that all elements will be initialized to.</param>
866+
/// <returns>A new <see cref="Vector256{IntPtr}" /> with all elements initialized to <paramref name="value" />.</returns>
867+
[Intrinsic]
868+
public static unsafe Vector256<nint> Create(nint value)
869+
{
870+
if (Avx.IsSupported)
871+
{
872+
return Create(value);
873+
}
874+
875+
return SoftwareFallback(value);
876+
877+
static Vector256<nint> SoftwareFallback(nint value)
878+
{
879+
if (Environment.Is64BitProcess)
880+
{
881+
return Create((long)value).AsNInt();
882+
}
883+
else
884+
{
885+
return Create((int)value).AsNInt();
886+
}
887+
}
888+
}
889+
890+
/// <summary>Creates a new <see cref="Vector256{UIntPtr}" /> instance with all elements initialized to the specified value.</summary>
891+
/// <param name="value">The value that all elements will be initialized to.</param>
892+
/// <returns>A new <see cref="Vector256{UIntPtr}" /> with all elements initialized to <paramref name="value" />.</returns>
893+
[Intrinsic]
894+
[CLSCompliant(false)]
895+
public static unsafe Vector256<nuint> Create(nuint value)
896+
{
897+
if (Avx.IsSupported)
898+
{
899+
return Create(value);
900+
}
901+
902+
return SoftwareFallback(value);
903+
904+
static Vector256<nuint> SoftwareFallback(nuint value)
905+
{
906+
if (Environment.Is64BitProcess)
907+
{
908+
return Create((ulong)value).AsNUInt();
909+
}
910+
else
911+
{
912+
return Create((uint)value).AsNUInt();
913+
}
914+
}
915+
}
916+
845917
/// <summary>Creates a new <see cref="Vector256{SByte}" /> instance with all elements initialized to the specified value.</summary>
846918
/// <param name="value">The value that all elements will be initialized to.</param>
847919
/// <remarks>On x86, this method corresponds to __m256i _mm256_set1_epi8</remarks>
@@ -1967,6 +2039,59 @@ static Vector256<long> SoftwareFallback(long value)
19672039
}
19682040
}
19692041

2042+
/// <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>
2043+
/// <param name="value">The value that element 0 will be initialized to.</param>
2044+
/// <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>
2045+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2046+
public static unsafe Vector256<nint> CreateScalar(nint value)
2047+
{
2048+
if (Avx.IsSupported)
2049+
{
2050+
return Create(value);
2051+
}
2052+
2053+
return SoftwareFallback(value);
2054+
2055+
static Vector256<nint> SoftwareFallback(nint value)
2056+
{
2057+
if (Environment.Is64BitProcess)
2058+
{
2059+
return CreateScalar((long)value).AsNInt();
2060+
}
2061+
else
2062+
{
2063+
return CreateScalar((int)value).AsNInt();
2064+
}
2065+
}
2066+
}
2067+
2068+
/// <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>
2069+
/// <param name="value">The value that element 0 will be initialized to.</param>
2070+
/// <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>
2071+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2072+
[CLSCompliant(false)]
2073+
public static unsafe Vector256<nuint> CreateScalar(nuint value)
2074+
{
2075+
if (Avx.IsSupported)
2076+
{
2077+
return Create(value);
2078+
}
2079+
2080+
return SoftwareFallback(value);
2081+
2082+
static Vector256<nuint> SoftwareFallback(nuint value)
2083+
{
2084+
if (Environment.Is64BitProcess)
2085+
{
2086+
return CreateScalar((ulong)value).AsNUInt();
2087+
}
2088+
else
2089+
{
2090+
return CreateScalar((uint)value).AsNUInt();
2091+
}
2092+
}
2093+
}
2094+
19702095
/// <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>
19712096
/// <param name="value">The value that element 0 will be initialized to.</param>
19722097
/// <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>
@@ -2146,6 +2271,39 @@ public static unsafe Vector256<long> CreateScalarUnsafe(long value)
21462271
return Unsafe.AsRef<Vector256<long>>(pResult);
21472272
}
21482273

2274+
/// <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>
2275+
/// <param name="value">The value that element 0 will be initialized to.</param>
2276+
/// <returns>A new <see cref="Vector256{IntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements left uninitialized.</returns>
2277+
[Intrinsic]
2278+
public static unsafe Vector256<nint> CreateScalarUnsafe(nint value)
2279+
{
2280+
if (Environment.Is64BitProcess)
2281+
{
2282+
return CreateScalarUnsafe((long)value).AsNInt();
2283+
}
2284+
else
2285+
{
2286+
return CreateScalarUnsafe((int)value).AsNInt();
2287+
}
2288+
}
2289+
2290+
/// <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>
2291+
/// <param name="value">The value that element 0 will be initialized to.</param>
2292+
/// <returns>A new <see cref="Vector256{UIntPtr}" /> instance with the first element initialized to <paramref name="value"/> and the remaining elements left uninitialized.</returns>
2293+
[Intrinsic]
2294+
[CLSCompliant(false)]
2295+
public static unsafe Vector256<nuint> CreateScalarUnsafe(nuint value)
2296+
{
2297+
if (Environment.Is64BitProcess)
2298+
{
2299+
return CreateScalarUnsafe((ulong)value).AsNUInt();
2300+
}
2301+
else
2302+
{
2303+
return CreateScalarUnsafe((uint)value).AsNUInt();
2304+
}
2305+
}
2306+
21492307
/// <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>
21502308
/// <param name="value">The value that element 0 will be initialized to.</param>
21512309
/// <returns>A new <see cref="Vector256{SByte}" /> instance with the first element initialized to <paramref name="value" /> and the remaining elements left uninitialized.</returns>

0 commit comments

Comments
 (0)