From 9906682033b4fee6aadc12ac878ffa8fde1edfe1 Mon Sep 17 00:00:00 2001 From: Ruihan-Yin <107431934+Ruihan-Yin@users.noreply.github.com> Date: Sat, 29 Jun 2024 08:24:01 -0700 Subject: [PATCH] remove unnecessary Avx512VL ISA flags. (#103144) * remove Avx10v1_V512 from XArchIntrisicConstants, let it imply by Avx512 and Avx10v1. * assert Avx10/V512 can be inferred from Avx10v1 and Avx512. --- .../Compiler/HardwareIntrinsicHelpers.cs | 9 +++--- .../Compiler/HardwareIntrinsicHelpers.Aot.cs | 29 +++++++++++++++---- src/coreclr/vm/codeman.cpp | 10 +++---- src/native/minipal/cpufeatures.c | 12 ++++---- src/native/minipal/cpufeatures.h | 3 +- 5 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/coreclr/tools/Common/Compiler/HardwareIntrinsicHelpers.cs b/src/coreclr/tools/Common/Compiler/HardwareIntrinsicHelpers.cs index a5f498ebc57a2..04657754110d4 100644 --- a/src/coreclr/tools/Common/Compiler/HardwareIntrinsicHelpers.cs +++ b/src/coreclr/tools/Common/Compiler/HardwareIntrinsicHelpers.cs @@ -74,8 +74,7 @@ private static class XArchIntrinsicConstants public const int Avx512Vbmi = 0x10000; public const int Serialize = 0x20000; public const int Avx10v1 = 0x40000; - public const int Avx10v1_v512 = 0x80000; - public const int Evex = 0x100000; + public const int Evex = 0x80000; public static void AddToBuilder(InstructionSetSupportBuilder builder, int flags) { @@ -129,7 +128,7 @@ public static void AddToBuilder(InstructionSetSupportBuilder builder, int flags) builder.AddSupportedInstructionSet("serialize"); if ((flags & Avx10v1) != 0) builder.AddSupportedInstructionSet("avx10v1"); - if ((flags & Avx10v1_v512) != 0) + if (((flags & Avx10v1) != 0) && ((flags & Avx512) != 0)) builder.AddSupportedInstructionSet("avx10v1_v512"); if ((flags & Evex) != 0) builder.AddSupportedInstructionSet("evex"); @@ -198,8 +197,8 @@ public static int FromInstructionSet(InstructionSet instructionSet) InstructionSet.X64_X86Serialize_X64 => Serialize, InstructionSet.X64_AVX10v1 => Avx10v1, InstructionSet.X64_AVX10v1_X64 => Avx10v1, - InstructionSet.X64_AVX10v1_V512 => Avx10v1_v512, - InstructionSet.X64_AVX10v1_V512_X64 => Avx10v1_v512, + InstructionSet.X64_AVX10v1_V512 => (Avx10v1 | Avx512), + InstructionSet.X64_AVX10v1_V512_X64 => (Avx10v1 | Avx512), InstructionSet.X64_EVEX => Evex, InstructionSet.X64_EVEX_X64 => Evex, diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicHelpers.Aot.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicHelpers.Aot.cs index ee355b964404d..85e7a943dba4a 100644 --- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicHelpers.Aot.cs +++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/HardwareIntrinsicHelpers.Aot.cs @@ -49,12 +49,29 @@ public static MethodIL EmitIsSupportedIL(MethodDesc method, FieldDesc isSupporte var emit = new ILEmitter(); ILCodeStream codeStream = emit.NewCodeStream(); - codeStream.Emit(ILOpcode.ldsfld, emit.NewToken(isSupportedField)); - codeStream.EmitLdc(flag); - codeStream.Emit(ILOpcode.and); - codeStream.EmitLdc(0); - codeStream.Emit(ILOpcode.cgt_un); - codeStream.Emit(ILOpcode.ret); + if(!uint.IsPow2((uint)flag)) + { + // These are the ISAs managed by multiple-bit flags. + // we need to emit different IL to handle the checks. + // For now just Avx10v1_V512 = (Avx10v1 | Avx512) + // (isSupportedField & flag) == flag + codeStream.Emit(ILOpcode.ldsfld, emit.NewToken(isSupportedField)); + codeStream.EmitLdc(flag); + codeStream.Emit(ILOpcode.and); + codeStream.EmitLdc(flag); + codeStream.Emit(ILOpcode.ceq); + codeStream.Emit(ILOpcode.ret); + } + else + { + // (isSupportedField & flag) >= (unsigned)0 + codeStream.Emit(ILOpcode.ldsfld, emit.NewToken(isSupportedField)); + codeStream.EmitLdc(flag); + codeStream.Emit(ILOpcode.and); + codeStream.EmitLdc(0); + codeStream.Emit(ILOpcode.cgt_un); + codeStream.Emit(ILOpcode.ret); + } return emit.Link(method); } diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index 6a293acdf466c..fc8dfbb2778d1 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -1433,12 +1433,12 @@ void EEJitManager::SetCpuInfo() { CPUCompileFlags.Set(InstructionSet_EVEX); CPUCompileFlags.Set(InstructionSet_AVX10v1); - } - } - if ((cpuFeatures & XArchIntrinsicConstants_Avx10v1_V512) != 0) - { - CPUCompileFlags.Set(InstructionSet_AVX10v1_V512); + if((cpuFeatures & XArchIntrinsicConstants_Avx512) != 0) + { + CPUCompileFlags.Set(InstructionSet_AVX10v1_V512); + } + } } #elif defined(TARGET_ARM64) diff --git a/src/native/minipal/cpufeatures.c b/src/native/minipal/cpufeatures.c index 47327255e40e2..8d6a063ce4d2f 100644 --- a/src/native/minipal/cpufeatures.c +++ b/src/native/minipal/cpufeatures.c @@ -263,13 +263,11 @@ int minipal_getcpufeatures(void) { result |= XArchIntrinsicConstants_Evex; result |= XArchIntrinsicConstants_Avx10v1; - - bool isV512Supported = (cpuidInfo[CPUID_EBX] & (1 << 18)) != 0; // Avx10/V512 - - if (isV512Supported) - { - result |= XArchIntrinsicConstants_Avx10v1_V512; - } + + // We assume that the Avx10/V512 support can be inferred from + // both Avx10v1 and Avx512 being present. + assert(((cpuidInfo[CPUID_EBX] & (1 << 18)) != 0) == // Avx10/V512 + ((result & XArchIntrinsicConstants_Avx512) != 0)); } } } diff --git a/src/native/minipal/cpufeatures.h b/src/native/minipal/cpufeatures.h index 52527a4565036..6422fe33f9787 100644 --- a/src/native/minipal/cpufeatures.h +++ b/src/native/minipal/cpufeatures.h @@ -30,8 +30,7 @@ enum XArchIntrinsicConstants XArchIntrinsicConstants_Avx512Vbmi = 0x10000, XArchIntrinsicConstants_Serialize = 0x20000, XArchIntrinsicConstants_Avx10v1 = 0x40000, - XArchIntrinsicConstants_Avx10v1_V512 = 0x80000, - XArchIntrinsicConstants_Evex = 0x100000, + XArchIntrinsicConstants_Evex = 0x80000, }; #endif // HOST_X86 || HOST_AMD64