]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Fix illegal instruction usage in Xeon Phi x200 processors
authorTulio Magno Quites Machado Filho <tuliom@redhat.com>
Tue, 14 May 2024 14:06:46 +0000 (11:06 -0300)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Sun, 19 May 2024 10:25:01 +0000 (12:25 +0200)
The Xeon Phi x200 family of processors (Knights Landing) supports
AVX512 (F, CD, ER, PF) but does not support AVX512 (VL, DQ, BW).

Because of processors like this, the Intel Software Developer's Manual
suggests the bits AVX512 (DQ,BW,VL) are also tested in EBX together with
AVX512F before deciding to run AVX512 (DQ,BW,VL) instructions.

This also adds a new x86 feature called avx512_common that indicates
that AVX512 (F,DQ,BW,VL) are all available and start using this for both
adler32_avx512 and crc32_vpclmulqdq implementations because they are
both built with -mavx512dq -mavx512bw -mavx512vl.

This has been reported downstream as
https://bugzilla.redhat.com/show_bug.cgi?id=2280347 .

arch/x86/x86_features.c
arch/x86/x86_features.h
functable.c
test/benchmarks/benchmark_adler32.cc
test/benchmarks/benchmark_adler32_copy.cc
test/benchmarks/benchmark_crc32.cc
test/test_adler32.cc
test/test_crc32.cc

index 450429cb9283780d5792599e1f9ae391ac532737..58cb4df341f2a5b45fce0ab52efc01610f4d84df 100644 (file)
@@ -99,7 +99,16 @@ void Z_INTERNAL x86_check_features(struct x86_cpu_features *features) {
 
         // check AVX512 bits if the OS supports saving ZMM registers
         if (features->has_os_save_zmm) {
-            features->has_avx512 = ebx & 0x00010000;
+            features->has_avx512f = ebx & 0x00010000;
+            if (features->has_avx512f) {
+                // According to the Intel Software Developer's Manual, AVX512F must be enabled too in order to enable
+                // AVX512(DQ,BW,VL).
+                features->has_avx512dq = ebx & 0x00020000;
+                features->has_avx512bw = ebx & 0x40000000;
+                features->has_avx512vl = ebx & 0x80000000;
+            }
+            features->has_avx512_common = features->has_avx512f && features->has_avx512dq && features->has_avx512bw \
+              && features->has_avx512vl;
             features->has_avx512vnni = ecx & 0x800;
         }
     }
index fc56ae2f446a479fc21332d0134e42367acea10f..6daa5e38282ffc5b318e2381ffe139aa3ee50ecd 100644 (file)
@@ -8,7 +8,11 @@
 
 struct x86_cpu_features {
     int has_avx2;
-    int has_avx512;
+    int has_avx512f;
+    int has_avx512dq;
+    int has_avx512bw;
+    int has_avx512vl;
+    int has_avx512_common; // Enabled when AVX512(F,DQ,BW,VL) are all enabled.
     int has_avx512vnni;
     int has_sse2;
     int has_ssse3;
index 8012a40b11b428cc9bb0bdb1f413046f4d626377..495d11edd20081ea0d9c690b94968c55b4bad436 100644 (file)
@@ -125,7 +125,7 @@ static void init_functable(void) {
 #endif
     // X86 - AVX512 (F,DQ,BW,Vl)
 #ifdef X86_AVX512
-    if (cf.x86.has_avx512) {
+    if (cf.x86.has_avx512_common) {
         ft.adler32 = &adler32_avx512;
         ft.adler32_fold_copy = &adler32_fold_copy_avx512;
     }
@@ -138,7 +138,7 @@ static void init_functable(void) {
 #endif
     // X86 - VPCLMULQDQ
 #ifdef X86_VPCLMULQDQ_CRC
-    if (cf.x86.has_pclmulqdq && cf.x86.has_avx512 && cf.x86.has_vpclmulqdq) {
+    if (cf.x86.has_pclmulqdq && cf.x86.has_avx512_common && cf.x86.has_vpclmulqdq) {
         ft.crc32 = &crc32_vpclmulqdq;
         ft.crc32_fold = &crc32_fold_vpclmulqdq;
         ft.crc32_fold_copy = &crc32_fold_vpclmulqdq_copy;
index 84f0d617c2bf01937a54924f7e17a94f3379970f..b1278950d0766bcf48cefb65ff5078c2701296ca 100644 (file)
@@ -91,7 +91,7 @@ BENCHMARK_ADLER32(ssse3, adler32_ssse3, test_cpu_features.x86.has_ssse3);
 BENCHMARK_ADLER32(avx2, adler32_avx2, test_cpu_features.x86.has_avx2);
 #endif
 #ifdef X86_AVX512
-BENCHMARK_ADLER32(avx512, adler32_avx512, test_cpu_features.x86.has_avx512);
+BENCHMARK_ADLER32(avx512, adler32_avx512, test_cpu_features.x86.has_avx512_common);
 #endif
 #ifdef X86_AVX512VNNI
 BENCHMARK_ADLER32(avx512_vnni, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni);
index e052ee76d0eca0fc536a4c5e4fdcafe8e26826b9..50e6333c43a4b5ccd37c79e080db6fb7d60e381c 100644 (file)
@@ -119,8 +119,8 @@ BENCHMARK_ADLER32_BASELINE_COPY(avx2_baseline, adler32_avx2, test_cpu_features.x
 BENCHMARK_ADLER32_COPY(avx2, adler32_fold_copy_avx2, test_cpu_features.x86.has_avx2);
 #endif
 #ifdef X86_AVX512
-BENCHMARK_ADLER32_BASELINE_COPY(avx512_baseline, adler32_avx512, test_cpu_features.x86.has_avx512);
-BENCHMARK_ADLER32_COPY(avx512, adler32_fold_copy_avx512, test_cpu_features.x86.has_avx512);
+BENCHMARK_ADLER32_BASELINE_COPY(avx512_baseline, adler32_avx512, test_cpu_features.x86.has_avx512_common);
+BENCHMARK_ADLER32_COPY(avx512, adler32_fold_copy_avx512, test_cpu_features.x86.has_avx512_common);
 #endif
 #ifdef X86_AVX512VNNI
 BENCHMARK_ADLER32_BASELINE_COPY(avx512_vnni_baseline, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni);
index 8611b280521208dafbc5fe84446ffa2c1a866bd0..7aba7c33674deb2fb0ccbb96f45f20ba200b32e5 100644 (file)
@@ -77,7 +77,7 @@ BENCHMARK_CRC32(pclmulqdq, crc32_pclmulqdq, test_cpu_features.x86.has_pclmulqdq)
 #endif
 #ifdef X86_VPCLMULQDQ_CRC
 /* CRC32 fold does a memory copy while hashing */
-BENCHMARK_CRC32(vpclmulqdq, crc32_vpclmulqdq, (test_cpu_features.x86.has_pclmulqdq && test_cpu_features.x86.has_avx512 && test_cpu_features.x86.has_vpclmulqdq));
+BENCHMARK_CRC32(vpclmulqdq, crc32_vpclmulqdq, (test_cpu_features.x86.has_pclmulqdq && test_cpu_features.x86.has_avx512_common && test_cpu_features.x86.has_vpclmulqdq));
 #endif
 
 #endif
index 85c4c78bbc5d730f31612cd6d0a8e2ef82aed2f8..b3d03021e4be5a096a726ea79dc1ca05cfaf78cd 100644 (file)
@@ -386,7 +386,7 @@ TEST_ADLER32(ssse3, adler32_ssse3, test_cpu_features.x86.has_ssse3)
 TEST_ADLER32(avx2, adler32_avx2, test_cpu_features.x86.has_avx2)
 #endif
 #ifdef X86_AVX512
-TEST_ADLER32(avx512, adler32_avx512, test_cpu_features.x86.has_avx512)
+TEST_ADLER32(avx512, adler32_avx512, test_cpu_features.x86.has_avx512_common)
 #endif
 #ifdef X86_AVX512VNNI
 TEST_ADLER32(avx512_vnni, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni)
index f8322085e6fa45634812ecb9ba1aa259294eb7fe..245a92fb949978926d2cdf333fcaf7a220f533c8 100644 (file)
@@ -225,7 +225,7 @@ TEST_CRC32(vx, crc32_s390_vx, test_cpu_features.s390.has_vx)
 TEST_CRC32(pclmulqdq, crc32_pclmulqdq, test_cpu_features.x86.has_pclmulqdq)
 #endif
 #ifdef X86_VPCLMULQDQ_CRC
-TEST_CRC32(vpclmulqdq, crc32_vpclmulqdq, (test_cpu_features.x86.has_pclmulqdq && test_cpu_features.x86.has_avx512 && test_cpu_features.x86.has_vpclmulqdq))
+TEST_CRC32(vpclmulqdq, crc32_vpclmulqdq, (test_cpu_features.x86.has_pclmulqdq && test_cpu_features.x86.has_avx512_common && test_cpu_features.x86.has_vpclmulqdq))
 #endif
 
 #endif