From 19291ccf33f1ca130c08eebd3f1cabbee751cd7c Mon Sep 17 00:00:00 2001 From: Egor Bogatov Date: Thu, 27 Jan 2022 13:57:09 +0300 Subject: [PATCH] Vector256.IsHardwareAccelerated to return true only on AVX2 (#64345) --- src/coreclr/jit/hwintrinsic.cpp | 21 ++++++++++++++++++- .../src/System/SpanHelpers.Byte.cs | 4 ++-- .../src/System/SpanHelpers.Char.cs | 4 ++-- .../JitBlue/Runtime_34587/Runtime_34587.cs | 2 +- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 0a5559dfd4122..fe9729ee7a9f1 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -285,7 +285,26 @@ NamedIntrinsic HWIntrinsicInfo::lookupId(Compiler* comp, bool isIsaSupported = comp->compSupportsHWIntrinsic(isa); - if ((strcmp(methodName, "get_IsSupported") == 0) || (strcmp(methodName, "get_IsHardwareAccelerated") == 0)) + bool isHardwareAcceleratedProp = (strcmp(methodName, "get_IsHardwareAccelerated") == 0); +#ifdef TARGET_XARCH + if (isHardwareAcceleratedProp) + { + // Special case: Some of Vector128/256 APIs are hardware accelerated with Sse1 and Avx1, + // but we want IsHardwareAccelerated to return true only when all of them are (there are + // still can be cases where e.g. Sse41 might give an additional boost for Vector128, but it's + // not important enough to bump the minimal Sse version here) + if (strcmp(className, "Vector128") == 0) + { + isa = InstructionSet_SSE2; + } + else if (strcmp(className, "Vector256") == 0) + { + isa = InstructionSet_AVX2; + } + } +#endif + + if ((strcmp(methodName, "get_IsSupported") == 0) || isHardwareAcceleratedProp) { return isIsaSupported ? (comp->compExactlyDependsOn(isa) ? NI_IsSupported_True : NI_IsSupported_Dynamic) : NI_IsSupported_False; diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs index 3a3bc586912ae..ddab1018c7ad4 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs @@ -64,7 +64,7 @@ ref Unsafe.Add(ref searchSpace, offset + 1), // Based on http://0x80.pl/articles/simd-strfind.html#algorithm-1-generic-simd "Algorithm 1: Generic SIMD" by Wojciech Muła // Some details about the implementation can also be found in https://github.com/dotnet/runtime/pull/63285 SEARCH_TWO_BYTES: - if (Avx2.IsSupported && searchSpaceMinusValueTailLength - Vector256.Count >= 0) + if (Vector256.IsHardwareAccelerated && searchSpaceMinusValueTailLength - Vector256.Count >= 0) { // Find the last unique (which is not equal to ch1) byte // the algorithm is fine if both are equal, just a little bit less efficient @@ -212,7 +212,7 @@ ref Unsafe.Add(ref searchSpace, relativeIndex + 1), // Based on http://0x80.pl/articles/simd-strfind.html#algorithm-1-generic-simd "Algorithm 1: Generic SIMD" by Wojciech Muła // Some details about the implementation can also be found in https://github.com/dotnet/runtime/pull/63285 SEARCH_TWO_BYTES: - if (Avx2.IsSupported && searchSpaceMinusValueTailLength >= Vector256.Count) + if (Vector256.IsHardwareAccelerated && searchSpaceMinusValueTailLength >= Vector256.Count) { offset = searchSpaceMinusValueTailLength - Vector256.Count; diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs index fb00b062538f2..c8331dc152336 100644 --- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs +++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs @@ -70,7 +70,7 @@ ref Unsafe.As(ref Unsafe.Add(ref searchSpace, offset + 1)), // Based on http://0x80.pl/articles/simd-strfind.html#algorithm-1-generic-simd "Algorithm 1: Generic SIMD" by Wojciech Muła // Some details about the implementation can also be found in https://github.com/dotnet/runtime/pull/63285 SEARCH_TWO_CHARS: - if (Avx2.IsSupported && searchSpaceMinusValueTailLength - Vector256.Count >= 0) + if (Vector256.IsHardwareAccelerated && searchSpaceMinusValueTailLength - Vector256.Count >= 0) { // Find the last unique (which is not equal to ch1) character // the algorithm is fine if both are equal, just a little bit less efficient @@ -231,7 +231,7 @@ ref Unsafe.As(ref Unsafe.Add(ref searchSpace, relativeIndex + 1)), // Based on http://0x80.pl/articles/simd-strfind.html#algorithm-1-generic-simd "Algorithm 1: Generic SIMD" by Wojciech Muła // Some details about the implementation can also be found in https://github.com/dotnet/runtime/pull/63285 SEARCH_TWO_CHARS: - if (Avx2.IsSupported && searchSpaceMinusValueTailLength >= Vector256.Count) + if (Vector256.IsHardwareAccelerated && searchSpaceMinusValueTailLength >= Vector256.Count) { offset = searchSpaceMinusValueTailLength - Vector256.Count; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs b/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs index 543e6b5804158..656da5bdb1aaf 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_34587/Runtime_34587.cs @@ -664,7 +664,7 @@ static bool ValidateVector256() { bool succeeded = true; - if (Avx.IsSupported) + if (Avx2.IsSupported) { succeeded &= Vector256.IsHardwareAccelerated; succeeded &= Vector256.Count == 32;