diff --git a/src/libraries/System.Linq/src/System/Linq/MaxMin.cs b/src/libraries/System.Linq/src/System/Linq/MaxMin.cs index 7adf15a83dcd3e..02645ec2509f66 100644 --- a/src/libraries/System.Linq/src/System/Linq/MaxMin.cs +++ b/src/libraries/System.Linq/src/System/Linq/MaxMin.cs @@ -3,8 +3,6 @@ using System.Collections.Generic; using System.Numerics; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.Intrinsics; namespace System.Linq @@ -50,18 +48,19 @@ private static T MinMaxInteger(this IEnumerable source) } else if (!Vector256.IsHardwareAccelerated || !Vector256.IsSupported || span.Length < Vector256.Count) { - ref T current = ref MemoryMarshal.GetReference(span); - ref T lastVectorStart = ref Unsafe.Add(ref current, span.Length - Vector128.Count); + // Capture the trailing overlapping vector before slicing, so it remains valid + // even when span.Length == Vector128.Count (in which case it equals the first vector). + ReadOnlySpan lastVec = span.Slice(span.Length - Vector128.Count); - Vector128 best = Vector128.LoadUnsafe(ref current); - current = ref Unsafe.Add(ref current, Vector128.Count); + Vector128 best = Vector128.Create(span); + span = span.Slice(Vector128.Count); - while (Unsafe.IsAddressLessThan(ref current, ref lastVectorStart)) + while (span.Length >= Vector128.Count) { - best = TMinMax.Compare(best, Vector128.LoadUnsafe(ref current)); - current = ref Unsafe.Add(ref current, Vector128.Count); + best = TMinMax.Compare(best, Vector128.Create(span)); + span = span.Slice(Vector128.Count); } - best = TMinMax.Compare(best, Vector128.LoadUnsafe(ref lastVectorStart)); + best = TMinMax.Compare(best, Vector128.Create(lastVec)); value = best[0]; for (int i = 1; i < Vector128.Count; i++) @@ -74,18 +73,17 @@ private static T MinMaxInteger(this IEnumerable source) } else if (!Vector512.IsHardwareAccelerated || !Vector512.IsSupported || span.Length < Vector512.Count) { - ref T current = ref MemoryMarshal.GetReference(span); - ref T lastVectorStart = ref Unsafe.Add(ref current, span.Length - Vector256.Count); + ReadOnlySpan lastVec = span.Slice(span.Length - Vector256.Count); - Vector256 best = Vector256.LoadUnsafe(ref current); - current = ref Unsafe.Add(ref current, Vector256.Count); + Vector256 best = Vector256.Create(span); + span = span.Slice(Vector256.Count); - while (Unsafe.IsAddressLessThan(ref current, ref lastVectorStart)) + while (span.Length >= Vector256.Count) { - best = TMinMax.Compare(best, Vector256.LoadUnsafe(ref current)); - current = ref Unsafe.Add(ref current, Vector256.Count); + best = TMinMax.Compare(best, Vector256.Create(span)); + span = span.Slice(Vector256.Count); } - best = TMinMax.Compare(best, Vector256.LoadUnsafe(ref lastVectorStart)); + best = TMinMax.Compare(best, Vector256.Create(lastVec)); value = best[0]; for (int i = 1; i < Vector256.Count; i++) @@ -98,18 +96,17 @@ private static T MinMaxInteger(this IEnumerable source) } else { - ref T current = ref MemoryMarshal.GetReference(span); - ref T lastVectorStart = ref Unsafe.Add(ref current, span.Length - Vector512.Count); + ReadOnlySpan lastVec = span.Slice(span.Length - Vector512.Count); - Vector512 best = Vector512.LoadUnsafe(ref current); - current = ref Unsafe.Add(ref current, Vector512.Count); + Vector512 best = Vector512.Create(span); + span = span.Slice(Vector512.Count); - while (Unsafe.IsAddressLessThan(ref current, ref lastVectorStart)) + while (span.Length >= Vector512.Count) { - best = TMinMax.Compare(best, Vector512.LoadUnsafe(ref current)); - current = ref Unsafe.Add(ref current, Vector512.Count); + best = TMinMax.Compare(best, Vector512.Create(span)); + span = span.Slice(Vector512.Count); } - best = TMinMax.Compare(best, Vector512.LoadUnsafe(ref lastVectorStart)); + best = TMinMax.Compare(best, Vector512.Create(lastVec)); value = best[0]; for (int i = 1; i < Vector512.Count; i++) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs index 1cebc6f55a6b81..7fd489621bc4d4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs @@ -31,6 +31,7 @@ namespace System.Runtime.Intrinsics // the internal inlining limits of the JIT. /// Provides a collection of static methods for creating, manipulating, and otherwise operating on 128-bit vectors. + [Intrinsic] public static partial class Vector128 { internal const int Size = 16; diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs index cd446c7646ac03..a37b61f96f3250 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256.cs @@ -29,6 +29,7 @@ namespace System.Runtime.Intrinsics // the internal inlining limits of the JIT. /// Provides a collection of static methods for creating, manipulating, and otherwise operating on 256-bit vectors. + [Intrinsic] public static class Vector256 { internal const int Size = 32; diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs index 6e71109c3ab9c5..82579167f18df6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512.cs @@ -28,6 +28,7 @@ namespace System.Runtime.Intrinsics // the internal inlining limits of the JIT. /// Provides a collection of static methods for creating, manipulating, and otherwise operting on 512-bit vectors. + [Intrinsic] public static class Vector512 { internal const int Size = 64; diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs index 8655d9778f0529..8383ef3d020154 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64.cs @@ -11,6 +11,7 @@ namespace System.Runtime.Intrinsics { /// Provides a collection of static methods for creating, manipulating, and otherwise operating on 64-bit vectors. + [Intrinsic] public static class Vector64 { internal const int Size = 8;