Skip to content

Commit 0806c67

Browse files
Update the naot instruction set support for .NET 10+ (#2828)
* Update the naot instruction set support for .NET 10+ * Apply suggestions from code review * Apply suggestions from code review Co-authored-by: Tim Cassell <[email protected]> * Apply suggestions from code review --------- Co-authored-by: Tim Cassell <[email protected]>
1 parent e704adb commit 0806c67

File tree

2 files changed

+179
-195
lines changed

2 files changed

+179
-195
lines changed

src/BenchmarkDotNet/Detectors/Cpu/HardwareIntrinsics.cs

Lines changed: 118 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,40 @@
1111

1212
namespace BenchmarkDotNet.Detectors.Cpu
1313
{
14+
// based on https://github.com/dotnet/runtime/tree/v10.0.0-rc.1.25451.107/src/coreclr/tools/Common/JitInterface/ThunkGenerator/InstructionSetDesc.txt
1415
internal static class HardwareIntrinsics
1516
{
1617
internal static string GetVectorSize() => Vector.IsHardwareAccelerated ? $"VectorSize={Vector<byte>.Count * 8}" : string.Empty;
1718

1819
internal static string GetShortInfo()
1920
{
20-
if (IsX86Avx512FSupported)
21-
return GetShortAvx512Representation();
22-
if (IsX86Avx2Supported)
23-
return "AVX2";
24-
else if (IsX86AvxSupported)
25-
return "AVX";
26-
else if (IsX86Sse42Supported)
27-
return "SSE4.2";
28-
else if (IsX86Sse41Supported)
29-
return "SSE4.1";
30-
else if (IsX86Ssse3Supported)
31-
return "SSSE3";
32-
else if (IsX86Sse3Supported)
33-
return "SSE3";
34-
else if (IsX86Sse2Supported)
35-
return "SSE2";
36-
else if (IsX86SseSupported)
37-
return "SSE";
38-
else if (IsX86BaseSupported)
39-
return "X86Base";
40-
else if (IsArmAdvSimdSupported)
41-
return "AdvSIMD";
21+
if (IsX86BaseSupported)
22+
{
23+
if (IsX86Avx512Supported)
24+
{
25+
return "x86-64-v4";
26+
}
27+
else if (IsX86Avx2Supported)
28+
{
29+
return "x86-64-v3";
30+
}
31+
else if (IsX86Sse42Supported)
32+
{
33+
return "x86-64-v2";
34+
}
35+
else
36+
{
37+
return "x86-64-v1";
38+
}
39+
}
4240
else if (IsArmBaseSupported)
43-
return "ArmBase";
41+
{
42+
return "armv8.0-a";
43+
}
4444
else
45+
{
4546
return GetVectorSize(); // Runtimes prior to .NET Core 3.0 (APIs did not exist so we print non-exact Vector info)
47+
}
4648
}
4749

4850
internal static string GetFullInfo(Platform platform)
@@ -55,32 +57,31 @@ static IEnumerable<string> GetCurrentProcessInstructionSets(Platform platform)
5557
{
5658
case Platform.X86:
5759
case Platform.X64:
58-
59-
if (IsX86Avx512FSupported) yield return GetShortAvx512Representation();
60-
else if (IsX86Avx2Supported) yield return "AVX2";
61-
else if (IsX86AvxSupported) yield return "AVX";
62-
else if (IsX86Sse42Supported) yield return "SSE4.2";
63-
else if (IsX86Sse41Supported) yield return "SSE4.1";
64-
else if (IsX86Ssse3Supported) yield return "SSSE3";
65-
else if (IsX86Sse3Supported) yield return "SSE3";
66-
else if (IsX86Sse2Supported) yield return "SSE2";
67-
else if (IsX86SseSupported) yield return "SSE";
68-
else if (IsX86BaseSupported) yield return "X86Base";
69-
70-
if (IsX86AesSupported) yield return "AES";
71-
if (IsX86Bmi1Supported) yield return "BMI1";
72-
if (IsX86Bmi2Supported) yield return "BMI2";
73-
if (IsX86FmaSupported) yield return "FMA";
74-
if (IsX86LzcntSupported) yield return "LZCNT";
75-
if (IsX86PclmulqdqSupported) yield return "PCLMUL";
76-
if (IsX86PopcntSupported) yield return "POPCNT";
60+
{
61+
if (IsX86Avx10v2Supported) yield return "AVX10v2";
62+
if (IsX86Avx10v1Supported)
63+
{
64+
yield return "AVX10v1";
65+
yield return "AVX512 BF16+FP16";
66+
}
67+
if (IsX86Avx512v3Supported) yield return "AVX512 BITALG+VBMI2+VNNI+VPOPCNTDQ";
68+
if (IsX86Avx512v2Supported) yield return "AVX512 IFMA+VBMI";
69+
if (IsX86Avx512Supported) yield return "AVX512 F+BW+CD+DQ+VL";
70+
if (IsX86Avx2Supported) yield return "AVX2+BMI1+BMI2+F16C+FMA+LZCNT+MOVBE";
71+
if (IsX86AvxSupported) yield return "AVX";
72+
if (IsX86Sse42Supported) yield return "SSE3+SSSE3+SSE4.1+SSE4.2+POPCNT";
73+
if (IsX86BaseSupported) yield return "X86Base+SSE+SSE2";
74+
if (IsX86AesSupported) yield return "AES+PCLMUL";
7775
if (IsX86AvxVnniSupported) yield return "AvxVnni";
7876
if (IsX86SerializeSupported) yield return "SERIALIZE";
79-
// TODO: Add MOVBE when API is added.
8077
break;
78+
}
8179
case Platform.Arm64:
82-
if (IsArmAdvSimdSupported) yield return "AdvSIMD";
83-
else if (IsArmBaseSupported) yield return "ArmBase";
80+
{
81+
if (IsArmBaseSupported)
82+
{
83+
yield return "ArmBase+AdvSimd";
84+
}
8485

8586
if (IsArmAesSupported) yield return "AES";
8687
if (IsArmCrc32Supported) yield return "CRC32";
@@ -89,71 +90,39 @@ static IEnumerable<string> GetCurrentProcessInstructionSets(Platform platform)
8990
if (IsArmSha1Supported) yield return "SHA1";
9091
if (IsArmSha256Supported) yield return "SHA256";
9192
break;
93+
}
94+
9295
default:
9396
yield break;
9497
}
9598
}
9699
}
97100

98-
private static string GetShortAvx512Representation()
99-
{
100-
StringBuilder avx512 = new("AVX-512F");
101-
if (IsX86Avx512CDSupported) avx512.Append("+CD");
102-
if (IsX86Avx512BWSupported) avx512.Append("+BW");
103-
if (IsX86Avx512DQSupported) avx512.Append("+DQ");
104-
if (IsX86Avx512FVLSupported) avx512.Append("+VL");
105-
if (IsX86Avx512VbmiSupported) avx512.Append("+VBMI");
106-
107-
return avx512.ToString();
108-
}
109-
101+
#pragma warning disable CA2252 // Some APIs require opting into preview features
110102
internal static bool IsX86BaseSupported =>
111103
#if NET6_0_OR_GREATER
112-
X86Base.IsSupported;
113-
#elif NETSTANDARD
114-
GetIsSupported("System.Runtime.Intrinsics.X86.X86Base");
115-
#endif
116-
117-
internal static bool IsX86SseSupported =>
118-
#if NET6_0_OR_GREATER
119-
Sse.IsSupported;
120-
#elif NETSTANDARD
121-
GetIsSupported("System.Runtime.Intrinsics.X86.Sse");
122-
#endif
123-
124-
internal static bool IsX86Sse2Supported =>
125-
#if NET6_0_OR_GREATER
104+
X86Base.IsSupported &&
105+
Sse.IsSupported &&
126106
Sse2.IsSupported;
127107
#elif NETSTANDARD
108+
GetIsSupported("System.Runtime.Intrinsics.X86.X86Base") &&
109+
GetIsSupported("System.Runtime.Intrinsics.X86.Sse") &&
128110
GetIsSupported("System.Runtime.Intrinsics.X86.Sse2");
129111
#endif
130112

131-
internal static bool IsX86Sse3Supported =>
132-
#if NET6_0_OR_GREATER
133-
Sse3.IsSupported;
134-
#elif NETSTANDARD
135-
GetIsSupported("System.Runtime.Intrinsics.X86.Sse3");
136-
#endif
137-
138-
internal static bool IsX86Ssse3Supported =>
139-
#if NET6_0_OR_GREATER
140-
Ssse3.IsSupported;
141-
#elif NETSTANDARD
142-
GetIsSupported("System.Runtime.Intrinsics.X86.Ssse3");
143-
#endif
144-
145-
internal static bool IsX86Sse41Supported =>
146-
#if NET6_0_OR_GREATER
147-
Sse41.IsSupported;
148-
#elif NETSTANDARD
149-
GetIsSupported("System.Runtime.Intrinsics.X86.Sse41");
150-
#endif
151-
152113
internal static bool IsX86Sse42Supported =>
153114
#if NET6_0_OR_GREATER
154-
Sse42.IsSupported;
115+
Sse3.IsSupported &&
116+
Ssse3.IsSupported &&
117+
Sse41.IsSupported &&
118+
Sse42.IsSupported &&
119+
Popcnt.IsSupported;
155120
#elif NETSTANDARD
156-
GetIsSupported("System.Runtime.Intrinsics.X86.Sse42");
121+
GetIsSupported("System.Runtime.Intrinsics.X86.Sse3") &&
122+
GetIsSupported("System.Runtime.Intrinsics.X86.Ssse3") &&
123+
GetIsSupported("System.Runtime.Intrinsics.X86.Sse41") &&
124+
GetIsSupported("System.Runtime.Intrinsics.X86.Sse42") &&
125+
GetIsSupported("System.Runtime.Intrinsics.X86.Popcnt");
157126
#endif
158127

159128
internal static bool IsX86AvxSupported =>
@@ -165,107 +134,88 @@ private static string GetShortAvx512Representation()
165134

166135
internal static bool IsX86Avx2Supported =>
167136
#if NET6_0_OR_GREATER
168-
Avx2.IsSupported;
137+
Avx2.IsSupported &&
138+
Bmi1.IsSupported &&
139+
Bmi2.IsSupported &&
140+
Fma.IsSupported &&
141+
Lzcnt.IsSupported;
169142
#elif NETSTANDARD
170-
GetIsSupported("System.Runtime.Intrinsics.X86.Avx2");
171-
#endif
172-
173-
internal static bool IsX86Avx512FSupported =>
174-
#if NET8_0_OR_GREATER
175-
Avx512F.IsSupported;
176-
#else
177-
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512F");
143+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx2") &&
144+
GetIsSupported("System.Runtime.Intrinsics.X86.Bmi1") &&
145+
GetIsSupported("System.Runtime.Intrinsics.X86.Bmi2") &&
146+
GetIsSupported("System.Runtime.Intrinsics.X86.Fma") &&
147+
GetIsSupported("System.Runtime.Intrinsics.X86.Lzcnt");
178148
#endif
179149

180-
internal static bool IsX86Avx512FVLSupported =>
150+
internal static bool IsX86Avx512Supported =>
181151
#if NET8_0_OR_GREATER
182-
Avx512F.VL.IsSupported;
152+
Avx512F.IsSupported &&
153+
Avx512F.VL.IsSupported &&
154+
Avx512BW.IsSupported &&
155+
Avx512BW.VL.IsSupported &&
156+
Avx512CD.IsSupported &&
157+
Avx512CD.VL.IsSupported &&
158+
Avx512DQ.IsSupported &&
159+
Avx512DQ.VL.IsSupported;
183160
#else
184-
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512F+VL");
161+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512F") &&
162+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512F+VL") &&
163+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512BW") &&
164+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512BW+VL") &&
165+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512CD") &&
166+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512CD+VL") &&
167+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512DQ") &&
168+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512DQ+VL");
185169
#endif
186170

187-
internal static bool IsX86Avx512BWSupported =>
171+
internal static bool IsX86Avx512v2Supported =>
188172
#if NET8_0_OR_GREATER
189-
Avx512BW.IsSupported;
173+
Avx512Vbmi.IsSupported &&
174+
Avx512Vbmi.VL.IsSupported;
190175
#else
191-
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512BW");
176+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512Vbmi") &&
177+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512Vbmi+VL");
192178
#endif
193179

194-
internal static bool IsX86Avx512CDSupported =>
195-
#if NET8_0_OR_GREATER
196-
Avx512CD.IsSupported;
180+
internal static bool IsX86Avx512v3Supported =>
181+
#if NET10_0_OR_GREATER
182+
Avx512Vbmi2.IsSupported &&
183+
Avx512Vbmi2.VL.IsSupported;
197184
#else
198-
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512CD");
185+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512Vbmi2") &&
186+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512Vbmi2+VL");
199187
#endif
200188

201-
internal static bool IsX86Avx512DQSupported =>
202-
#if NET8_0_OR_GREATER
203-
Avx512DQ.IsSupported;
189+
internal static bool IsX86Avx10v1Supported =>
190+
#if NET9_0_OR_GREATER
191+
Avx10v1.IsSupported &&
192+
Avx10v1.V512.IsSupported;
204193
#else
205-
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512DQ");
194+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx10v1") &&
195+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx10v1+V512");
206196
#endif
207197

208-
internal static bool IsX86Avx512VbmiSupported =>
209-
#if NET8_0_OR_GREATER
210-
Avx512Vbmi.IsSupported;
198+
internal static bool IsX86Avx10v2Supported =>
199+
#if NET10_0_OR_GREATER
200+
Avx10v2.IsSupported &&
201+
Avx10v2.V512.IsSupported;
211202
#else
212-
GetIsSupported("System.Runtime.Intrinsics.X86.Avx512Vbmi");
203+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx10v2") &&
204+
GetIsSupported("System.Runtime.Intrinsics.X86.Avx10v2+V512");
213205
#endif
214206

215207
internal static bool IsX86AesSupported =>
216208
#if NET6_0_OR_GREATER
217-
System.Runtime.Intrinsics.X86.Aes.IsSupported;
218-
#elif NETSTANDARD
219-
GetIsSupported("System.Runtime.Intrinsics.X86.Aes");
220-
#endif
221-
222-
internal static bool IsX86Bmi1Supported =>
223-
#if NET6_0_OR_GREATER
224-
Bmi1.IsSupported;
225-
#elif NETSTANDARD
226-
GetIsSupported("System.Runtime.Intrinsics.X86.Bmi1");
227-
#endif
228-
229-
internal static bool IsX86Bmi2Supported =>
230-
#if NET6_0_OR_GREATER
231-
Bmi2.IsSupported;
232-
#elif NETSTANDARD
233-
GetIsSupported("System.Runtime.Intrinsics.X86.Bmi2");
234-
#endif
235-
236-
internal static bool IsX86FmaSupported =>
237-
#if NET6_0_OR_GREATER
238-
Fma.IsSupported;
239-
#elif NETSTANDARD
240-
GetIsSupported("System.Runtime.Intrinsics.X86.Fma");
241-
#endif
242-
243-
internal static bool IsX86LzcntSupported =>
244-
#if NET6_0_OR_GREATER
245-
Lzcnt.IsSupported;
246-
#elif NETSTANDARD
247-
GetIsSupported("System.Runtime.Intrinsics.X86.Lzcnt");
248-
#endif
249-
250-
internal static bool IsX86PclmulqdqSupported =>
251-
#if NET6_0_OR_GREATER
209+
System.Runtime.Intrinsics.X86.Aes.IsSupported &&
252210
Pclmulqdq.IsSupported;
253211
#elif NETSTANDARD
212+
GetIsSupported("System.Runtime.Intrinsics.X86.Aes") &&
254213
GetIsSupported("System.Runtime.Intrinsics.X86.Pclmulqdq");
255214
#endif
256215

257-
internal static bool IsX86PopcntSupported =>
258-
#if NET6_0_OR_GREATER
259-
Popcnt.IsSupported;
260-
#elif NETSTANDARD
261-
GetIsSupported("System.Runtime.Intrinsics.X86.Popcnt");
262-
#endif
263-
264216
internal static bool IsX86AvxVnniSupported =>
265217
#if NET6_0_OR_GREATER
266-
#pragma warning disable CA2252 // This API requires opting into preview features
267218
AvxVnni.IsSupported;
268-
#pragma warning restore CA2252 // This API requires opting into preview features
269219
#elif NETSTANDARD
270220
GetIsSupported("System.Runtime.Intrinsics.X86.AvxVnni");
271221
#endif
@@ -279,15 +229,10 @@ private static string GetShortAvx512Representation()
279229

280230
internal static bool IsArmBaseSupported =>
281231
#if NET6_0_OR_GREATER
282-
ArmBase.IsSupported;
283-
#elif NETSTANDARD
284-
GetIsSupported("System.Runtime.Intrinsics.Arm.ArmBase");
285-
#endif
286-
287-
internal static bool IsArmAdvSimdSupported =>
288-
#if NET6_0_OR_GREATER
232+
ArmBase.IsSupported &&
289233
AdvSimd.IsSupported;
290234
#elif NETSTANDARD
235+
GetIsSupported("System.Runtime.Intrinsics.Arm.ArmBase") &&
291236
GetIsSupported("System.Runtime.Intrinsics.Arm.AdvSimd");
292237
#endif
293238

@@ -332,6 +277,7 @@ private static string GetShortAvx512Representation()
332277
#elif NETSTANDARD
333278
GetIsSupported("System.Runtime.Intrinsics.Arm.Sha256");
334279
#endif
280+
#pragma warning restore CA2252 // Some APIs require opting into preview features
335281

336282
private static bool GetIsSupported([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] string typeName)
337283
{

0 commit comments

Comments
 (0)