diff --git a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs index 0f399d2de..6fef04316 100644 --- a/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs +++ b/src/ImageSharp/Common/Helpers/SimdUtils.HwIntrinsics.cs @@ -66,9 +66,9 @@ internal static partial class SimdUtils ref Span destination, [ConstantExpected] byte control) { - if ((Vector512.IsHardwareAccelerated && Vector512_.SupportsShuffleNativeFloat) || - (Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleNativeFloat) || - Vector128.IsHardwareAccelerated) + if (Vector512.IsHardwareAccelerated || + Vector256.IsHardwareAccelerated || + Vector128.IsHardwareAccelerated) { int remainder = 0; if (Vector512.IsHardwareAccelerated) @@ -112,8 +112,8 @@ internal static partial class SimdUtils ref Span destination, [ConstantExpected] byte control) { - if ((Vector512.IsHardwareAccelerated && Vector512_.SupportsShuffleNativeByte) || - (Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleNativeByte) || + if (Vector512.IsHardwareAccelerated || + Vector256.IsHardwareAccelerated || Vector128.IsHardwareAccelerated) { int remainder = 0; @@ -249,7 +249,7 @@ internal static partial class SimdUtils Span destination, [ConstantExpected] byte control) { - if (Vector512.IsHardwareAccelerated && Vector512_.SupportsShuffleNativeFloat) + if (Vector512.IsHardwareAccelerated) { ref Vector512 sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); ref Vector512 destinationBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(destination)); @@ -277,7 +277,7 @@ internal static partial class SimdUtils } } } - else if (Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleNativeFloat) + else if (Vector256.IsHardwareAccelerated) { ref Vector256 sourceBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(source)); ref Vector256 destinationBase = ref Unsafe.As>(ref MemoryMarshal.GetReference(destination)); @@ -341,7 +341,7 @@ internal static partial class SimdUtils Span destination, [ConstantExpected] byte control) { - if (Vector512.IsHardwareAccelerated && Vector512_.SupportsShuffleNativeByte) + if (Vector512.IsHardwareAccelerated) { Span temp = stackalloc byte[Vector512.Count]; Shuffle.MMShuffleSpan(ref temp, control); @@ -373,7 +373,7 @@ internal static partial class SimdUtils } } } - else if (Vector256.IsHardwareAccelerated && Vector256_.SupportsShuffleNativeByte) + else if (Vector256.IsHardwareAccelerated) { Span temp = stackalloc byte[Vector256.Count]; Shuffle.MMShuffleSpan(ref temp, control); diff --git a/src/ImageSharp/Common/Helpers/Vector128Utilities.cs b/src/ImageSharp/Common/Helpers/Vector128Utilities.cs index 4492b297c..1676f69d1 100644 --- a/src/ImageSharp/Common/Helpers/Vector128Utilities.cs +++ b/src/ImageSharp/Common/Helpers/Vector128Utilities.cs @@ -1323,7 +1323,9 @@ internal static class Vector128_ { // https://stackoverflow.com/questions/11870910/sse-mm-movemask-epi8-equivalent-method-for-arm-neon Vector128 powers = Vector128.Create(1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128); - Vector128 masked = value & powers; + Vector128 msbMask = Vector128.Create((byte)0x80); + Vector128 normalized = AdvSimd.CompareEqual(value & msbMask, msbMask); // 0xFF or 0x00 + Vector128 masked = normalized & powers; Vector128 sum8 = AdvSimd.AddPairwiseWidening(masked); Vector128 sum16 = AdvSimd.AddPairwiseWidening(sum8); diff --git a/src/ImageSharp/Common/Helpers/Vector256Utilities.cs b/src/ImageSharp/Common/Helpers/Vector256Utilities.cs index e61dcb6bf..e1c40107f 100644 --- a/src/ImageSharp/Common/Helpers/Vector256Utilities.cs +++ b/src/ImageSharp/Common/Helpers/Vector256Utilities.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; @@ -21,24 +20,6 @@ namespace SixLabors.ImageSharp.Common.Helpers; internal static class Vector256_ #pragma warning restore SA1649 // File name should match first type name { - /// - /// Gets a value indicating whether shuffle byte operations are supported. - /// - public static bool SupportsShuffleNativeFloat - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Avx.IsSupported; - } - - /// - /// Gets a value indicating whether shuffle byte operations are supported. - /// - public static bool SupportsShuffleNativeByte - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Avx2.IsSupported; - } - /// /// Creates a new vector by selecting values from an input vector using a set of indices. /// @@ -47,15 +28,7 @@ internal static class Vector256_ /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 ShuffleNative(Vector256 vector, [ConstantExpected] byte control) - { - if (Avx.IsSupported) - { - return Avx.Shuffle(vector, vector, control); - } - - ThrowUnreachableException(); - return default; - } + => Avx.Shuffle(vector, vector, control); /// /// Creates a new vector by selecting values from an input vector using a set of indices. @@ -73,8 +46,9 @@ internal static class Vector256_ return Avx2.Shuffle(vector, indices); } - ThrowUnreachableException(); - return default; + return Vector256.Create( + Vector128_.ShuffleNative(vector.GetLower(), indices.GetLower()), + Vector128_.ShuffleNative(vector.GetUpper(), indices.GetUpper())); } /// @@ -508,7 +482,4 @@ internal static class Vector256_ int hiMask = Vector128_.MoveMask(value.GetUpper()); return loMask | (hiMask << 16); } - - [DoesNotReturn] - private static void ThrowUnreachableException() => throw new UnreachableException(); } diff --git a/src/ImageSharp/Common/Helpers/Vector512Utilities.cs b/src/ImageSharp/Common/Helpers/Vector512Utilities.cs index 63de5dc10..ded47f48e 100644 --- a/src/ImageSharp/Common/Helpers/Vector512Utilities.cs +++ b/src/ImageSharp/Common/Helpers/Vector512Utilities.cs @@ -1,7 +1,6 @@ // Copyright (c) Six Labors. // Licensed under the Six Labors Split License. -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics; @@ -21,24 +20,6 @@ namespace SixLabors.ImageSharp.Common.Helpers; internal static class Vector512_ #pragma warning restore SA1649 // File name should match first type name { - /// - /// Gets a value indicating whether shuffle float operations are supported. - /// - public static bool SupportsShuffleNativeFloat - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Avx512F.IsSupported; - } - - /// - /// Gets a value indicating whether shuffle byte operations are supported. - /// - public static bool SupportsShuffleNativeByte - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => Avx512BW.IsSupported; - } - /// /// Creates a new vector by selecting values from an input vector using the control. /// @@ -47,15 +28,7 @@ internal static class Vector512_ /// The . [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 ShuffleNative(Vector512 vector, [ConstantExpected] byte control) - { - if (Avx512F.IsSupported) - { - return Avx512F.Shuffle(vector, vector, control); - } - - ThrowUnreachableException(); - return default; - } + => Avx512F.Shuffle(vector, vector, control); /// /// Creates a new vector by selecting values from an input vector using a set of indices. @@ -73,8 +46,9 @@ internal static class Vector512_ return Avx512BW.Shuffle(vector, indices); } - ThrowUnreachableException(); - return default; + return Vector512.Create( + Vector256_.ShuffleNative(vector.GetLower(), indices.GetLower()), + Vector256_.ShuffleNative(vector.GetUpper(), indices.GetUpper())); } /// @@ -175,7 +149,4 @@ internal static class Vector512_ [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector512 Clamp(Vector512 value, Vector512 min, Vector512 max) => Vector512.Min(Vector512.Max(value, min), max); - - [DoesNotReturn] - private static void ThrowUnreachableException() => throw new UnreachableException(); } diff --git a/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs b/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs index 5c6fb5604..a0930c75b 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/ColorSpaceTransformUtils.cs @@ -12,7 +12,7 @@ internal static class ColorSpaceTransformUtils { public static void CollectColorBlueTransforms(Span bgra, int stride, int tileWidth, int tileHeight, int greenToBlue, int redToBlue, Span histo) { - if (Vector256_.SupportsShuffleNativeByte && tileWidth >= 16) + if (Vector256.IsHardwareAccelerated && tileWidth >= 16) { const int span = 16; Span values = stackalloc ushort[span];