]> 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>
Wed, 19 Jun 2024 12:15:54 +0000 (14:15 +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 3f37e7f205a45b2b56ceac4a0fae095f71f2191b..48d577d4cbea42b52dc3b7e59e38b38a31ee64f6 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 4a36bde835d32efc64f19a7968456a03f698ee1b..5a2abdfc44369ff2323a267088064c82bcc41f90 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 37c4aeef7d0e8732954f45d2266f2d82ce9b8117..fd1be2f5beedc22168e0cb13dd36d68e834f2794 100644 (file)
@@ -152,7 +152,7 @@ static void init_functable(void) {
     }
 #endif
 #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;
     }
@@ -165,7 +165,7 @@ static void init_functable(void) {
 #endif
     // X86 - VPCLMULQDQ
 #if defined(X86_PCLMULQDQ_CRC) && defined(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 0be3a707a59c3e31838ddb2857ee464c2f2d2e0c..61edb949aa81d1027a5f83317919705e987e2188 100644 (file)
@@ -86,7 +86,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 9a4a5ff420d18f656ac1f71ed6e1623cba5d150a..ba56687acf703cdf36f1d925f13e82828bb607df 100644 (file)
@@ -114,8 +114,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 f73c308d8fc2c1217bf8d1e802a52d2054e6d699..d4ddf7caed66eeefcfeda1290172bd2166de2bc0 100644 (file)
@@ -72,5 +72,5 @@ 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
index 1ed6e224861e2ed7e8bde659a43944a162edbfc7..da90f36da2029156be75fdbf3b4e68a2b7be5e57 100644 (file)
@@ -381,7 +381,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 0cdc31791bad5958eb5b96dec56ff74244a2a96e..12e48905c2f6bc48c9c3639f69cc1de9ce3f6f48 100644 (file)
@@ -221,5 +221,5 @@ 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