diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/BitArray.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/BitArray.cs index a325147a8f0bc5..39797ba0bb7f75 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Collections/BitArray.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Collections/BitArray.cs @@ -170,44 +170,50 @@ public BitArray(bool[] values) // Instead, We compare with zeroes (== false) then negate the result to ensure compatibility. ref byte arrayRef = ref MemoryMarshal.GetArrayDataReference(_array); - ref byte value = ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference(values)); + ReadOnlySpan valuesAsBytes = MemoryMarshal.AsBytes(values.AsSpan()); if (Vector512.IsHardwareAccelerated) { - for (; i <= (uint)values.Length - Vector512.Count; i += (uint)Vector512.Count) + while (valuesAsBytes.Length >= Vector512.Count) { - Vector512 vector = Vector512.LoadUnsafe(ref value, i); + Vector512 vector = Vector512.Create(valuesAsBytes); Vector512 isFalse = Vector512.Equals(vector, Vector512.Zero); ulong result = isFalse.ExtractMostSignificantBits(); Unsafe.WriteUnaligned(ref Unsafe.Add(ref arrayRef, sizeof(ulong) * (i / 64u)), ~result); + i += (uint)Vector512.Count; + valuesAsBytes = valuesAsBytes.Slice(Vector512.Count); } } else if (Vector256.IsHardwareAccelerated) { - for (; i <= (uint)values.Length - Vector256.Count; i += (uint)Vector256.Count) + while (valuesAsBytes.Length >= Vector256.Count) { - Vector256 vector = Vector256.LoadUnsafe(ref value, i); + Vector256 vector = Vector256.Create(valuesAsBytes); Vector256 isFalse = Vector256.Equals(vector, Vector256.Zero); uint result = isFalse.ExtractMostSignificantBits(); Unsafe.WriteUnaligned(ref Unsafe.Add(ref arrayRef, sizeof(uint) * (i / 32u)), ~result); + i += (uint)Vector256.Count; + valuesAsBytes = valuesAsBytes.Slice(Vector256.Count); } } else if (Vector128.IsHardwareAccelerated) { - for (; i <= (uint)values.Length - Vector128.Count * 2u; i += (uint)Vector128.Count * 2u) + while (valuesAsBytes.Length >= Vector128.Count * 2) { - Vector128 lowerVector = Vector128.LoadUnsafe(ref value, i); + Vector128 lowerVector = Vector128.Create(valuesAsBytes); Vector128 lowerIsFalse = Vector128.Equals(lowerVector, Vector128.Zero); uint lowerResult = lowerIsFalse.ExtractMostSignificantBits(); - Vector128 upperVector = Vector128.LoadUnsafe(ref value, i + (uint)Vector128.Count); + Vector128 upperVector = Vector128.Create(valuesAsBytes.Slice(Vector128.Count)); Vector128 upperIsFalse = Vector128.Equals(upperVector, Vector128.Zero); uint upperResult = upperIsFalse.ExtractMostSignificantBits(); Unsafe.WriteUnaligned( ref Unsafe.Add(ref arrayRef, sizeof(uint) * (i / 32u)), ~((upperResult << 16) | lowerResult)); + i += (uint)Vector128.Count * 2u; + valuesAsBytes = valuesAsBytes.Slice(Vector128.Count * 2); } }