From 164a3ed693f9aa80bcb3c9a77b8891a6169e498d Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Thu, 4 Sep 2025 13:49:21 -0700 Subject: [PATCH 1/4] Update the naot instruction set support for .NET 10+ --- .../Detectors/Cpu/HardwareIntrinsics.cs | 291 +++++++----------- .../Toolchains/NativeAot/Generator.cs | 84 +++-- 2 files changed, 180 insertions(+), 195 deletions(-) diff --git a/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs b/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs index 265143a356..00af560815 100644 --- a/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs +++ b/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs @@ -11,38 +11,40 @@ namespace BenchmarkDotNet.Detectors.Cpu { + // based on https://github.com/dotnet/runtime/blob/main/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt internal static class HardwareIntrinsics { internal static string GetVectorSize() => Vector.IsHardwareAccelerated ? $"VectorSize={Vector.Count * 8}" : string.Empty; internal static string GetShortInfo() { - if (IsX86Avx512FSupported) - return GetShortAvx512Representation(); - if (IsX86Avx2Supported) - return "AVX2"; - else if (IsX86AvxSupported) - return "AVX"; - else if (IsX86Sse42Supported) - return "SSE4.2"; - else if (IsX86Sse41Supported) - return "SSE4.1"; - else if (IsX86Ssse3Supported) - return "SSSE3"; - else if (IsX86Sse3Supported) - return "SSE3"; - else if (IsX86Sse2Supported) - return "SSE2"; - else if (IsX86SseSupported) - return "SSE"; - else if (IsX86BaseSupported) - return "X86Base"; - else if (IsArmAdvSimdSupported) - return "AdvSIMD"; + if (IsX86BaseSupported) + { + if (IsX86Avx512Supported) + { + return "x86-64-v4"; + } + else if (IsX86Avx2Supported) + { + return "x86-64-v3"; + } + else if (IsX86Sse42Supported) + { + return "x86-64-v2"; + } + else + { + return "x86-64-v1"; + } + } else if (IsArmBaseSupported) - return "ArmBase"; + { + return "armv8.0-a"; + } else + { return GetVectorSize(); // Runtimes prior to .NET Core 3.0 (APIs did not exist so we print non-exact Vector info) + } } internal static string GetFullInfo(Platform platform) @@ -55,32 +57,32 @@ static IEnumerable GetCurrentProcessInstructionSets(Platform platform) { case Platform.X86: case Platform.X64: - - if (IsX86Avx512FSupported) yield return GetShortAvx512Representation(); - else if (IsX86Avx2Supported) yield return "AVX2"; - else if (IsX86AvxSupported) yield return "AVX"; - else if (IsX86Sse42Supported) yield return "SSE4.2"; - else if (IsX86Sse41Supported) yield return "SSE4.1"; - else if (IsX86Ssse3Supported) yield return "SSSE3"; - else if (IsX86Sse3Supported) yield return "SSE3"; - else if (IsX86Sse2Supported) yield return "SSE2"; - else if (IsX86SseSupported) yield return "SSE"; - else if (IsX86BaseSupported) yield return "X86Base"; - - if (IsX86AesSupported) yield return "AES"; - if (IsX86Bmi1Supported) yield return "BMI1"; - if (IsX86Bmi2Supported) yield return "BMI2"; - if (IsX86FmaSupported) yield return "FMA"; - if (IsX86LzcntSupported) yield return "LZCNT"; - if (IsX86PclmulqdqSupported) yield return "PCLMUL"; - if (IsX86PopcntSupported) yield return "POPCNT"; + { + if (IsX86Avx10v2Supported) yield return "AVX10v2"; + if (IsX86Avx10v1Supported) + { + yield return "AVX10v1"; + yield return "AVX512 BF16+FP16" + } + if (IsX86Avx512v3Supported) yield return "AVX512 BITALG+VBMI2+VNNI+VPOPCNTDQ" + if (IsX86Avx512v2Supported) yield return "AVX512 IFMA+VBMI" + if (IsX86Avx512Supported) yield return "AVX512 F+BW+CD+DQ+VL"; + if (IsX86Avx2Supported) yield return "AVX2+BMI1+BMI2+F16C+FMA+LZCNT+MOVBE"; + if (IsX86AvxSupported) yield return "AVX"; + if (IsX86Sse42Supported) yield return "SSE3+SSSE3+SSE4.1+SSE4.2+POPCNT"; + if (IsX86BaseSupported) yield return "X86Base+SSE+SSE2"; + if (IsX86AesSupported) yield return "AES+PCLMUL"; if (IsX86AvxVnniSupported) yield return "AvxVnni"; if (IsX86SerializeSupported) yield return "SERIALIZE"; - // TODO: Add MOVBE when API is added. break; + } + case Platform.Arm64: - if (IsArmAdvSimdSupported) yield return "AdvSIMD"; - else if (IsArmBaseSupported) yield return "ArmBase"; + { + if (IsArmBaseSupported) + { + yield return "ArmBase+AdvSimd"; + } if (IsArmAesSupported) yield return "AES"; if (IsArmCrc32Supported) yield return "CRC32"; @@ -89,71 +91,39 @@ static IEnumerable GetCurrentProcessInstructionSets(Platform platform) if (IsArmSha1Supported) yield return "SHA1"; if (IsArmSha256Supported) yield return "SHA256"; break; + } + default: yield break; } } } - private static string GetShortAvx512Representation() - { - StringBuilder avx512 = new("AVX-512F"); - if (IsX86Avx512CDSupported) avx512.Append("+CD"); - if (IsX86Avx512BWSupported) avx512.Append("+BW"); - if (IsX86Avx512DQSupported) avx512.Append("+DQ"); - if (IsX86Avx512FVLSupported) avx512.Append("+VL"); - if (IsX86Avx512VbmiSupported) avx512.Append("+VBMI"); - - return avx512.ToString(); - } - +#pragma warning disable CA2252 // Some APIs require opting into preview features internal static bool IsX86BaseSupported => #if NET6_0_OR_GREATER - X86Base.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.X86Base"); -#endif - - internal static bool IsX86SseSupported => -#if NET6_0_OR_GREATER - Sse.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Sse"); -#endif - - internal static bool IsX86Sse2Supported => -#if NET6_0_OR_GREATER + X86Base.IsSupported && + Sse.IsSupported && Sse2.IsSupported; #elif NETSTANDARD + GetIsSupported("System.Runtime.Intrinsics.X86.X86Base") && + GetIsSupported("System.Runtime.Intrinsics.X86.Sse") GetIsSupported("System.Runtime.Intrinsics.X86.Sse2"); #endif - internal static bool IsX86Sse3Supported => -#if NET6_0_OR_GREATER - Sse3.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Sse3"); -#endif - - internal static bool IsX86Ssse3Supported => -#if NET6_0_OR_GREATER - Ssse3.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Ssse3"); -#endif - - internal static bool IsX86Sse41Supported => -#if NET6_0_OR_GREATER - Sse41.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Sse41"); -#endif - internal static bool IsX86Sse42Supported => #if NET6_0_OR_GREATER - Sse42.IsSupported; + Sse3.IsSupported && + Ssse3.IsSupported && + Sse41.IsSupported && + Sse42.IsSupported && + Popcnt.IsSupported; #elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Sse42"); + GetIsSupported("System.Runtime.Intrinsics.X86.Sse3") && + GetIsSupported("System.Runtime.Intrinsics.X86.Ssse3") && + GetIsSupported("System.Runtime.Intrinsics.X86.Sse41") && + GetIsSupported("System.Runtime.Intrinsics.X86.Sse42") && + GetIsSupported("System.Runtime.Intrinsics.X86.Popcnt"); #endif internal static bool IsX86AvxSupported => @@ -165,107 +135,88 @@ private static string GetShortAvx512Representation() internal static bool IsX86Avx2Supported => #if NET6_0_OR_GREATER - Avx2.IsSupported; + Avx2.IsSupported && + Bmi1.IsSupported && + Bmi2.IsSupported && + Fma.IsSupported && + Lzcnt.IsSupported; #elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Avx2"); -#endif - - internal static bool IsX86Avx512FSupported => -#if NET8_0_OR_GREATER - Avx512F.IsSupported; -#else - GetIsSupported("System.Runtime.Intrinsics.X86.Avx512F"); + GetIsSupported("System.Runtime.Intrinsics.X86.Avx2") && + GetIsSupported("System.Runtime.Intrinsics.X86.Bmi1") && + GetIsSupported("System.Runtime.Intrinsics.X86.Bmi2") && + GetIsSupported("System.Runtime.Intrinsics.X86.Fma") && + GetIsSupported("System.Runtime.Intrinsics.X86.Lzcnt"); #endif - internal static bool IsX86Avx512FVLSupported => + internal static bool IsX86Avx512Supported => #if NET8_0_OR_GREATER - Avx512F.VL.IsSupported; + Avx512F.IsSupported && + Avx512F.VL.IsSupported && + Avx512BW.IsSupported && + Avx512BW.VL.IsSupported && + Avx512CD.IsSupported && + Avx512CD.VL.IsSupported && + Avx512DQ.IsSupported && + Avx512DQ.VL.IsSupported; #else - GetIsSupported("System.Runtime.Intrinsics.X86.Avx512F+VL"); + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512F") && + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512F+VL") && + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512BW") && + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512BW+VL") && + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512CD") && + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512CD+VL") && + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512DQ") && + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512DQ+VL"); #endif - internal static bool IsX86Avx512BWSupported => + internal static bool IsX86Avx512v2Supported => #if NET8_0_OR_GREATER - Avx512BW.IsSupported; + Avx512Vbmi.IsSupported && + Avx512Vbmi.VL.IsSupported; #else - GetIsSupported("System.Runtime.Intrinsics.X86.Avx512BW"); + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512Vbmi") && + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512Vbmi+VL"); #endif - internal static bool IsX86Avx512CDSupported => -#if NET8_0_OR_GREATER - Avx512CD.IsSupported; + internal static bool IsX86Avx512v3Supported => +#if NET10_0_OR_GREATER + Avx512Vbmi2.IsSupported && + Avx512Vbmi2.VL.IsSupported; #else - GetIsSupported("System.Runtime.Intrinsics.X86.Avx512CD"); + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512Vbmi2") && + GetIsSupported("System.Runtime.Intrinsics.X86.Avx512Vbmi2+VL"); #endif - internal static bool IsX86Avx512DQSupported => -#if NET8_0_OR_GREATER - Avx512DQ.IsSupported; + internal static bool IsX86Avx10v1Supported => +#if NET9_0_OR_GREATER + Avx10v1.IsSupported && + Avx10v1.V512.IsSupported; #else - GetIsSupported("System.Runtime.Intrinsics.X86.Avx512DQ"); + GetIsSupported("System.Runtime.Intrinsics.X86.Avx10v1") && + GetIsSupported("System.Runtime.Intrinsics.X86.Avx10v1+V512"); #endif - internal static bool IsX86Avx512VbmiSupported => -#if NET8_0_OR_GREATER - Avx512Vbmi.IsSupported; + internal static bool IsX86Avx10v2Supported => +#if NET10_0_OR_GREATER + Avx10v2.IsSupported && + Avx10v2.V512.IsSupported; #else - GetIsSupported("System.Runtime.Intrinsics.X86.Avx512Vbmi"); + GetIsSupported("System.Runtime.Intrinsics.X86.Avx10v2") && + GetIsSupported("System.Runtime.Intrinsics.X86.Avx10v2+V512"); #endif internal static bool IsX86AesSupported => #if NET6_0_OR_GREATER - System.Runtime.Intrinsics.X86.Aes.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Aes"); -#endif - - internal static bool IsX86Bmi1Supported => -#if NET6_0_OR_GREATER - Bmi1.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Bmi1"); -#endif - - internal static bool IsX86Bmi2Supported => -#if NET6_0_OR_GREATER - Bmi2.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Bmi2"); -#endif - - internal static bool IsX86FmaSupported => -#if NET6_0_OR_GREATER - Fma.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Fma"); -#endif - - internal static bool IsX86LzcntSupported => -#if NET6_0_OR_GREATER - Lzcnt.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Lzcnt"); -#endif - - internal static bool IsX86PclmulqdqSupported => -#if NET6_0_OR_GREATER + System.Runtime.Intrinsics.X86.Aes.IsSupported && Pclmulqdq.IsSupported; #elif NETSTANDARD + GetIsSupported("System.Runtime.Intrinsics.X86.Aes") && GetIsSupported("System.Runtime.Intrinsics.X86.Pclmulqdq"); #endif - internal static bool IsX86PopcntSupported => -#if NET6_0_OR_GREATER - Popcnt.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.X86.Popcnt"); -#endif - internal static bool IsX86AvxVnniSupported => #if NET6_0_OR_GREATER -#pragma warning disable CA2252 // This API requires opting into preview features AvxVnni.IsSupported; -#pragma warning restore CA2252 // This API requires opting into preview features #elif NETSTANDARD GetIsSupported("System.Runtime.Intrinsics.X86.AvxVnni"); #endif @@ -279,15 +230,10 @@ private static string GetShortAvx512Representation() internal static bool IsArmBaseSupported => #if NET6_0_OR_GREATER - ArmBase.IsSupported; -#elif NETSTANDARD - GetIsSupported("System.Runtime.Intrinsics.Arm.ArmBase"); -#endif - - internal static bool IsArmAdvSimdSupported => -#if NET6_0_OR_GREATER + ArmBase.IsSupported && AdvSimd.IsSupported; #elif NETSTANDARD + GetIsSupported("System.Runtime.Intrinsics.Arm.ArmBase") && GetIsSupported("System.Runtime.Intrinsics.Arm.AdvSimd"); #endif @@ -332,6 +278,7 @@ private static string GetShortAvx512Representation() #elif NETSTANDARD GetIsSupported("System.Runtime.Intrinsics.Arm.Sha256"); #endif +#pragma warning restore CA2252 // Some APIs require opting into preview features private static bool GetIsSupported([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] string typeName) { diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs index f1e32d6c6b..17b4a26b7a 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs @@ -236,7 +236,7 @@ private void GenerateReflectionFile(ArtifactsPaths artifactsPaths) private string GetCurrentInstructionSet(Platform platform) => string.Join(",", GetCurrentProcessInstructionSets(platform)); - // based on https://github.com/dotnet/runtime/blob/ce61c09a5f6fc71d8f717d3fc4562f42171869a0/src/coreclr/tools/Common/JitInterface/CorInfoInstructionSet.cs#L727 + // based on https://github.com/dotnet/runtime/blob/main/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt private IEnumerable GetCurrentProcessInstructionSets(Platform platform) { if (!ConfigParser.TryParse(TargetFrameworkMoniker, out RuntimeMoniker runtimeMoniker)) @@ -256,39 +256,77 @@ private IEnumerable GetCurrentProcessInstructionSets(Platform platform) case Platform.X86: case Platform.X64: if (HardwareIntrinsics.IsX86BaseSupported) yield return "base"; - if (HardwareIntrinsics.IsX86SseSupported) yield return "sse"; - if (HardwareIntrinsics.IsX86Sse2Supported) yield return "sse2"; - if (HardwareIntrinsics.IsX86Sse3Supported) yield return "sse3"; - if (HardwareIntrinsics.IsX86Ssse3Supported) yield return "ssse3"; - if (HardwareIntrinsics.IsX86Sse41Supported) yield return "sse4.1"; - if (HardwareIntrinsics.IsX86Sse42Supported) yield return "sse4.2"; + if (HardwareIntrinsics.IsX86Sse42Supported) + { + yield return "sse4.2"; + if (runtimeMoniker <= RuntimeMoniker.NativeAot90) yield return "popcnt"; + } if (HardwareIntrinsics.IsX86AvxSupported) yield return "avx"; - if (HardwareIntrinsics.IsX86Avx2Supported) yield return "avx2"; - if (HardwareIntrinsics.IsX86Avx512FSupported) yield return "avx512f"; - if (HardwareIntrinsics.IsX86Avx512BWSupported) yield return "avx512bw"; - if (HardwareIntrinsics.IsX86Avx512CDSupported) yield return "avx512cd"; - if (HardwareIntrinsics.IsX86Avx512DQSupported) yield return "avx512dq"; - if (HardwareIntrinsics.IsX86Avx512VbmiSupported) yield return "avx512vbmi"; - if (HardwareIntrinsics.IsX86AesSupported) yield return "aes"; - if (HardwareIntrinsics.IsX86Bmi1Supported) yield return "bmi"; - if (HardwareIntrinsics.IsX86Bmi2Supported) yield return "bmi2"; - if (HardwareIntrinsics.IsX86FmaSupported) yield return "fma"; - if (HardwareIntrinsics.IsX86LzcntSupported) yield return "lzcnt"; - if (HardwareIntrinsics.IsX86PclmulqdqSupported) yield return "pclmul"; - if (HardwareIntrinsics.IsX86PopcntSupported) yield return "popcnt"; + if (HardwareIntrinsics.IsX86Avx2Supported) + { + yield return "avx2"; + + if (runtimeMoniker <= RuntimeMoniker.NativeAot90) + { + yield return "bmi"; + yield return "bmi2"; + yield return "fma"; + yield return "lzcnt"; + } + } + if (HardwareIntrinsics.IsX86Avx512Supported && (runtimeMoniker > RuntimeMoniker.NativeAot80)) + { + if (runtimeMoniker >= RuntimeMoniker.NativeAot10_0) + { + yield return "avx512"; + } + else + { + yield return "avx512f"; + yield return "avx512f_vl"; + yield return "avx512bw"; + yield return "avx512bw_vl"; + yield return "avx512cd"; + yield return "avx512cd_vl"; + yield return "avx512dq"; + yield return "avx512dq_vl"; + } + } + if (HardwareIntrinsics.IsX86Avx512v2Supported && (runtimeMoniker > RuntimeMoniker.NativeAot80)) + { + if (runtimeMoniker >= RuntimeMoniker.NativeAot10_0) + { + yield return "avx512v2"; + } + else + { + yield return "avx512vbmi"; + yield return "avx512vbmi_vl"; + } + } + if (HardwareIntrinsics.IsX86Avx512v3Supported && (runtimeMoniker >= RuntimeMoniker.NativeAot10_0)) yield return "avx512v3"; + if (HardwareIntrinsics.IsX86Avx10v1Supported && (runtimeMoniker >= RuntimeMoniker.NativeAot90)) yield return "avx10v1"; + if (HardwareIntrinsics.IsX86Avx10v2Supported && (runtimeMoniker >= RuntimeMoniker.NativeAot10_0)) yield return "avx10v2"; + if (HardwareIntrinsics.IsX86AesSupported) + { + yield return "aes"; + if (runtimeMoniker <= RuntimeMoniker.NativeAot90) yield return "pclmul"; + } if (HardwareIntrinsics.IsX86AvxVnniSupported) yield return "avxvnni"; if (HardwareIntrinsics.IsX86SerializeSupported && runtimeMoniker > RuntimeMoniker.NativeAot70) yield return "serialize"; // https://github.com/dotnet/BenchmarkDotNet/issues/2463#issuecomment-1809625008 break; case Platform.Arm64: - if (HardwareIntrinsics.IsArmBaseSupported) yield return "base"; - if (HardwareIntrinsics.IsArmAdvSimdSupported) yield return "neon"; + if (HardwareIntrinsics.IsArmBaseSupported) + { + yield return "base"; + yield return "neon"; + } if (HardwareIntrinsics.IsArmAesSupported) yield return "aes"; if (HardwareIntrinsics.IsArmCrc32Supported) yield return "crc"; if (HardwareIntrinsics.IsArmDpSupported) yield return "dotprod"; if (HardwareIntrinsics.IsArmRdmSupported) yield return "rdma"; if (HardwareIntrinsics.IsArmSha1Supported) yield return "sha1"; if (HardwareIntrinsics.IsArmSha256Supported) yield return "sha2"; - // todo: handle "lse" break; default: yield break; From 3949d57d94749cf9d46f43501972d0540b80cb2c Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 10 Sep 2025 09:19:00 -0700 Subject: [PATCH 2/4] Apply suggestions from code review --- src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs | 2 +- src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs b/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs index 00af560815..ed7cf50e75 100644 --- a/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs +++ b/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs @@ -11,7 +11,7 @@ namespace BenchmarkDotNet.Detectors.Cpu { - // based on https://github.com/dotnet/runtime/blob/main/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt + // based on https://github.com/dotnet/runtime/tree/v10.0.0-rc.1.25451.107/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt internal static class HardwareIntrinsics { internal static string GetVectorSize() => Vector.IsHardwareAccelerated ? $"VectorSize={Vector.Count * 8}" : string.Empty; diff --git a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs index 17b4a26b7a..e9c64a82f5 100644 --- a/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs +++ b/src/BenchmarkDotNet/Toolchains/NativeAot/Generator.cs @@ -236,7 +236,7 @@ private void GenerateReflectionFile(ArtifactsPaths artifactsPaths) private string GetCurrentInstructionSet(Platform platform) => string.Join(",", GetCurrentProcessInstructionSets(platform)); - // based on https://github.com/dotnet/runtime/blob/main/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt + // based on https://github.com/dotnet/runtime/tree/v10.0.0-rc.1.25451.107/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt private IEnumerable GetCurrentProcessInstructionSets(Platform platform) { if (!ConfigParser.TryParse(TargetFrameworkMoniker, out RuntimeMoniker runtimeMoniker)) @@ -258,7 +258,7 @@ private IEnumerable GetCurrentProcessInstructionSets(Platform platform) if (HardwareIntrinsics.IsX86BaseSupported) yield return "base"; if (HardwareIntrinsics.IsX86Sse42Supported) { - yield return "sse4.2"; + if (runtimeMoniker <= RuntimeMoniker.NativeAot10_0) yield return "sse4.2"; if (runtimeMoniker <= RuntimeMoniker.NativeAot90) yield return "popcnt"; } if (HardwareIntrinsics.IsX86AvxSupported) yield return "avx"; From 347cff210434d07f3d159cef1ec206f0b8ada295 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 10 Sep 2025 10:24:33 -0700 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Tim Cassell --- src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs b/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs index ed7cf50e75..eb5ab792b7 100644 --- a/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs +++ b/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs @@ -62,10 +62,10 @@ static IEnumerable GetCurrentProcessInstructionSets(Platform platform) if (IsX86Avx10v1Supported) { yield return "AVX10v1"; - yield return "AVX512 BF16+FP16" + yield return "AVX512 BF16+FP16"; } - if (IsX86Avx512v3Supported) yield return "AVX512 BITALG+VBMI2+VNNI+VPOPCNTDQ" - if (IsX86Avx512v2Supported) yield return "AVX512 IFMA+VBMI" + if (IsX86Avx512v3Supported) yield return "AVX512 BITALG+VBMI2+VNNI+VPOPCNTDQ"; + if (IsX86Avx512v2Supported) yield return "AVX512 IFMA+VBMI"; if (IsX86Avx512Supported) yield return "AVX512 F+BW+CD+DQ+VL"; if (IsX86Avx2Supported) yield return "AVX2+BMI1+BMI2+F16C+FMA+LZCNT+MOVBE"; if (IsX86AvxSupported) yield return "AVX"; @@ -107,7 +107,7 @@ static IEnumerable GetCurrentProcessInstructionSets(Platform platform) Sse2.IsSupported; #elif NETSTANDARD GetIsSupported("System.Runtime.Intrinsics.X86.X86Base") && - GetIsSupported("System.Runtime.Intrinsics.X86.Sse") + GetIsSupported("System.Runtime.Intrinsics.X86.Sse") && GetIsSupported("System.Runtime.Intrinsics.X86.Sse2"); #endif From 1225b94e5927944a2985f62d561fa8f3d528c4d7 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Wed, 10 Sep 2025 13:00:58 -0700 Subject: [PATCH 4/4] Apply suggestions from code review --- src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs b/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs index eb5ab792b7..5b2815cc43 100644 --- a/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs +++ b/src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs @@ -76,7 +76,6 @@ static IEnumerable GetCurrentProcessInstructionSets(Platform platform) if (IsX86SerializeSupported) yield return "SERIALIZE"; break; } - case Platform.Arm64: { if (IsArmBaseSupported)