From 0e4ed515b966b79764d5d919a9425b59bfff8850 Mon Sep 17 00:00:00 2001 From: Barinzaya Date: Mon, 14 Oct 2024 08:20:23 -0400 Subject: [PATCH 1/4] Added AVX-512 feature detection to core:sys/info. --- core/sys/info/cpu_intel.odin | 47 +++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/core/sys/info/cpu_intel.odin b/core/sys/info/cpu_intel.odin index d6fa98507..f42369e81 100644 --- a/core/sys/info/cpu_intel.odin +++ b/core/sys/info/cpu_intel.odin @@ -28,6 +28,25 @@ CPU_Feature :: enum u64 { ssse3, // Supplemental streaming SIMD extension 3 sse41, // Streaming SIMD extension 4 and 4.1 sse42, // Streaming SIMD extension 4 and 4.2 + + avx512_4fmaps, // Fused Multiply Accumulation Packed Single precision + avx512_4vnniw, // Vector Neural Network Instructions Word variable precision + avx512_bf16, // Vector Neural Network Instructions supporting bfloat16 + avx512_bitalg, // Bit Algorithms + avx512_bw, // Byte and Word instructions + avx512_cd, // Conflict Detection instructions + avx512_dq, // Doubleword and Quadword instructions + avx512_er, // Exponential and Reciprocal instructions + avx512_f, // Foundation + avx512_fp16, // Vector 16-bit float instructions + avx512_ifma, // Integer Fused Multiply Add + avx512_pf, // Prefetch instructions + avx512_vbmi, // Vector Byte Manipulation Instructions + avx512_vbmi2, // Vector Byte Manipulation Instructions 2 + avx512_vl, // Vector Length extensions + avx512_vnni, // Vector Neural Network Instructions + avx512_vp2intersect, // Vector Pair Intersection to a Pair of Mask Registers + avx512_vpopcntdq, // Vector Population Count for Doubleword and Quadword } CPU_Features :: distinct bit_set[CPU_Feature; u64] @@ -82,9 +101,11 @@ init_cpu_features :: proc "c" () { // // See: crbug.com/375968 os_supports_avx := false + os_supports_avx512 := false if .os_xsave in set && is_set(26, ecx1) { eax, _ := xgetbv(0) os_supports_avx = is_set(1, eax) && is_set(2, eax) + os_supports_avx512 = is_set(5, eax) && is_set(6, eax) && is_set(7, eax) } if os_supports_avx { try_set(&set, .avx, 28, ecx1) @@ -94,11 +115,35 @@ init_cpu_features :: proc "c" () { return } - _, ebx7, _, _ := cpuid(7, 0) + _, ebx7, ecx7, edx7 := cpuid(7, 0) try_set(&set, .bmi1, 3, ebx7) if os_supports_avx { try_set(&set, .avx2, 5, ebx7) } + if os_supports_avx512 { + try_set(&set, .avx512_f, 16, ebx7) + try_set(&set, .avx512_dq, 17, ebx7) + try_set(&set, .avx512_ifma, 21, ebx7) + try_set(&set, .avx512_pf, 26, ebx7) + try_set(&set, .avx512_er, 27, ebx7) + try_set(&set, .avx512_cd, 28, ebx7) + try_set(&set, .avx512_bw, 30, ebx7) + try_set(&set, .avx512_vl, 31, ebx7) + + try_set(&set, .avx512_vbmi, 1, ecx7) + try_set(&set, .avx512_vbmi2, 6, ecx7) + try_set(&set, .avx512_vnni, 11, ecx7) + try_set(&set, .avx512_bitalg, 12, ecx7) + try_set(&set, .avx512_vpopcntdq, 14, ecx7) + + try_set(&set, .avx512_4vnniw, 2, edx7) + try_set(&set, .avx512_4fmaps, 3, edx7) + try_set(&set, .avx512_vp2intersect, 8, edx7) + try_set(&set, .avx512_fp16, 23, edx7) + + eax7_1, _, _, _ := cpuid(7, 1) + try_set(&set, .avx512_bf16, 5, eax7_1) + } try_set(&set, .bmi2, 8, ebx7) try_set(&set, .erms, 9, ebx7) try_set(&set, .rdseed, 18, ebx7) From c93923c9f7609529304dcebab5005ea172cac4ae Mon Sep 17 00:00:00 2001 From: Barinzaya Date: Mon, 14 Oct 2024 08:53:16 -0400 Subject: [PATCH 2/4] Fixed formatting. --- core/sys/info/cpu_intel.odin | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/sys/info/cpu_intel.odin b/core/sys/info/cpu_intel.odin index f42369e81..d8ef21473 100644 --- a/core/sys/info/cpu_intel.odin +++ b/core/sys/info/cpu_intel.odin @@ -136,10 +136,10 @@ init_cpu_features :: proc "c" () { try_set(&set, .avx512_bitalg, 12, ecx7) try_set(&set, .avx512_vpopcntdq, 14, ecx7) - try_set(&set, .avx512_4vnniw, 2, edx7) - try_set(&set, .avx512_4fmaps, 3, edx7) - try_set(&set, .avx512_vp2intersect, 8, edx7) - try_set(&set, .avx512_fp16, 23, edx7) + try_set(&set, .avx512_4vnniw, 2, edx7) + try_set(&set, .avx512_4fmaps, 3, edx7) + try_set(&set, .avx512_vp2intersect, 8, edx7) + try_set(&set, .avx512_fp16, 23, edx7) eax7_1, _, _, _ := cpuid(7, 1) try_set(&set, .avx512_bf16, 5, eax7_1) From ff35a59548d12df4c0a51e991b70c85063ead639 Mon Sep 17 00:00:00 2001 From: Barinzaya Date: Mon, 14 Oct 2024 09:09:14 -0400 Subject: [PATCH 3/4] Fixed a theoretical edge case in AVX512VL support detection. --- core/sys/info/cpu_intel.odin | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/sys/info/cpu_intel.odin b/core/sys/info/cpu_intel.odin index d8ef21473..44272d93b 100644 --- a/core/sys/info/cpu_intel.odin +++ b/core/sys/info/cpu_intel.odin @@ -128,7 +128,11 @@ init_cpu_features :: proc "c" () { try_set(&set, .avx512_er, 27, ebx7) try_set(&set, .avx512_cd, 28, ebx7) try_set(&set, .avx512_bw, 30, ebx7) - try_set(&set, .avx512_vl, 31, ebx7) + + // XMM/YMM are also required for 128/256-bit instructions + if os_supports_avx { + try_set(&set, .avx512_vl, 31, ebx7) + } try_set(&set, .avx512_vbmi, 1, ecx7) try_set(&set, .avx512_vbmi2, 6, ecx7) From 872a29752c5f3d7a1ae89bb3099b64fd3c7da0f5 Mon Sep 17 00:00:00 2001 From: Barinzaya Date: Tue, 15 Oct 2024 05:21:22 -0400 Subject: [PATCH 4/4] Renamed and trimmed AVX-512 features in sys/info. Removed underscores from the AVX-512 names in `CPU_Feature` to make them match their equivalent LLVM target features. Removed 4FMAPs and 4VNNIW as there aren't matching LLVM target features. --- core/sys/info/cpu_intel.odin | 68 +++++++++++++++++------------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/core/sys/info/cpu_intel.odin b/core/sys/info/cpu_intel.odin index 44272d93b..95b53dda0 100644 --- a/core/sys/info/cpu_intel.odin +++ b/core/sys/info/cpu_intel.odin @@ -29,24 +29,22 @@ CPU_Feature :: enum u64 { sse41, // Streaming SIMD extension 4 and 4.1 sse42, // Streaming SIMD extension 4 and 4.2 - avx512_4fmaps, // Fused Multiply Accumulation Packed Single precision - avx512_4vnniw, // Vector Neural Network Instructions Word variable precision - avx512_bf16, // Vector Neural Network Instructions supporting bfloat16 - avx512_bitalg, // Bit Algorithms - avx512_bw, // Byte and Word instructions - avx512_cd, // Conflict Detection instructions - avx512_dq, // Doubleword and Quadword instructions - avx512_er, // Exponential and Reciprocal instructions - avx512_f, // Foundation - avx512_fp16, // Vector 16-bit float instructions - avx512_ifma, // Integer Fused Multiply Add - avx512_pf, // Prefetch instructions - avx512_vbmi, // Vector Byte Manipulation Instructions - avx512_vbmi2, // Vector Byte Manipulation Instructions 2 - avx512_vl, // Vector Length extensions - avx512_vnni, // Vector Neural Network Instructions - avx512_vp2intersect, // Vector Pair Intersection to a Pair of Mask Registers - avx512_vpopcntdq, // Vector Population Count for Doubleword and Quadword + avx512bf16, // Vector Neural Network Instructions supporting bfloat16 + avx512bitalg, // Bit Algorithms + avx512bw, // Byte and Word instructions + avx512cd, // Conflict Detection instructions + avx512dq, // Doubleword and Quadword instructions + avx512er, // Exponential and Reciprocal instructions + avx512f, // Foundation + avx512fp16, // Vector 16-bit float instructions + avx512ifma, // Integer Fused Multiply Add + avx512pf, // Prefetch instructions + avx512vbmi, // Vector Byte Manipulation Instructions + avx512vbmi2, // Vector Byte Manipulation Instructions 2 + avx512vl, // Vector Length extensions + avx512vnni, // Vector Neural Network Instructions + avx512vp2intersect, // Vector Pair Intersection to a Pair of Mask Registers + avx512vpopcntdq, // Vector Population Count for Doubleword and Quadword } CPU_Features :: distinct bit_set[CPU_Feature; u64] @@ -121,32 +119,30 @@ init_cpu_features :: proc "c" () { try_set(&set, .avx2, 5, ebx7) } if os_supports_avx512 { - try_set(&set, .avx512_f, 16, ebx7) - try_set(&set, .avx512_dq, 17, ebx7) - try_set(&set, .avx512_ifma, 21, ebx7) - try_set(&set, .avx512_pf, 26, ebx7) - try_set(&set, .avx512_er, 27, ebx7) - try_set(&set, .avx512_cd, 28, ebx7) - try_set(&set, .avx512_bw, 30, ebx7) + try_set(&set, .avx512f, 16, ebx7) + try_set(&set, .avx512dq, 17, ebx7) + try_set(&set, .avx512ifma, 21, ebx7) + try_set(&set, .avx512pf, 26, ebx7) + try_set(&set, .avx512er, 27, ebx7) + try_set(&set, .avx512cd, 28, ebx7) + try_set(&set, .avx512bw, 30, ebx7) // XMM/YMM are also required for 128/256-bit instructions if os_supports_avx { - try_set(&set, .avx512_vl, 31, ebx7) + try_set(&set, .avx512vl, 31, ebx7) } - try_set(&set, .avx512_vbmi, 1, ecx7) - try_set(&set, .avx512_vbmi2, 6, ecx7) - try_set(&set, .avx512_vnni, 11, ecx7) - try_set(&set, .avx512_bitalg, 12, ecx7) - try_set(&set, .avx512_vpopcntdq, 14, ecx7) + try_set(&set, .avx512vbmi, 1, ecx7) + try_set(&set, .avx512vbmi2, 6, ecx7) + try_set(&set, .avx512vnni, 11, ecx7) + try_set(&set, .avx512bitalg, 12, ecx7) + try_set(&set, .avx512vpopcntdq, 14, ecx7) - try_set(&set, .avx512_4vnniw, 2, edx7) - try_set(&set, .avx512_4fmaps, 3, edx7) - try_set(&set, .avx512_vp2intersect, 8, edx7) - try_set(&set, .avx512_fp16, 23, edx7) + try_set(&set, .avx512vp2intersect, 8, edx7) + try_set(&set, .avx512fp16, 23, edx7) eax7_1, _, _, _ := cpuid(7, 1) - try_set(&set, .avx512_bf16, 5, eax7_1) + try_set(&set, .avx512bf16, 5, eax7_1) } try_set(&set, .bmi2, 8, ebx7) try_set(&set, .erms, 9, ebx7)