From 522fd699e6753edb810bccb3e75d620237e2da45 Mon Sep 17 00:00:00 2001 From: Frank Barchard Date: Mon, 6 Nov 2017 12:29:30 -0800 Subject: [PATCH] AVX512 feature detects for cnl and icl Key instruction sets added for each microarchitecture: AVX512BW, AVX512VL, AVX512DQ - skylake server or later AVX512_VBMI, AVX512_IFMA - cannon lake or later AVX512_BITALG, AVX512_VBMI2, AVX512_VPOPCNTDQ, AVX512_VNNI, GFNI, VAES, VPCLMULQDQ - ice lake or later Bug: libyuv:752 Test: ~/intelsde/sde -icl -- out/Release/libyuv_unittest --gtest_filter=*Cpu* Change-Id: I9ee28904c90009d66721b9f805a440c5fc2da122 Reviewed-on: https://chromium-review.googlesource.com/755617 Reviewed-by: Frank Barchard Reviewed-by: richard winterton --- README.chromium | 2 +- docs/environment_variables.md | 2 +- include/libyuv/cpu_id.h | 18 +++++++++------- include/libyuv/version.h | 2 +- source/cpu_id.cc | 15 ++++++++++---- unit_test/cpu_test.cc | 39 +++++++++++++++++++++++++---------- util/cpuid.c | 18 +++++++++++++--- 7 files changed, 68 insertions(+), 28 deletions(-) diff --git a/README.chromium b/README.chromium index b78186a6a..be05cba3a 100644 --- a/README.chromium +++ b/README.chromium @@ -1,6 +1,6 @@ Name: libyuv URL: http://code.google.com/p/libyuv/ -Version: 1675 +Version: 1676 License: BSD License File: LICENSE diff --git a/docs/environment_variables.md b/docs/environment_variables.md index 5802599e9..9071c54de 100644 --- a/docs/environment_variables.md +++ b/docs/environment_variables.md @@ -14,7 +14,7 @@ By default the cpu is detected and the most advanced form of SIMD is used. But LIBYUV_DISABLE_SSE42 LIBYUV_DISABLE_AVX LIBYUV_DISABLE_AVX2 - LIBYUV_DISABLE_AVX3 + LIBYUV_DISABLE_AVX512BW LIBYUV_DISABLE_ERMS LIBYUV_DISABLE_FMA3 LIBYUV_DISABLE_DSPR2 diff --git a/include/libyuv/cpu_id.h b/include/libyuv/cpu_id.h index 6d1afbdbb..c2e9bbbd9 100644 --- a/include/libyuv/cpu_id.h +++ b/include/libyuv/cpu_id.h @@ -36,15 +36,19 @@ static const int kCpuHasAVX = 0x200; static const int kCpuHasAVX2 = 0x400; static const int kCpuHasERMS = 0x800; static const int kCpuHasFMA3 = 0x1000; -static const int kCpuHasAVX3 = 0x2000; -static const int kCpuHasF16C = 0x4000; - -// 0x8000 reserved for future X86 flags. +static const int kCpuHasF16C = 0x2000; +static const int kCpuHasGFNI = 0x4000; +static const int kCpuHasAVX512BW = 0x8000; +static const int kCpuHasAVX512VL = 0x10000; +static const int kCpuHasAVX512VBMI = 0x20000; +static const int kCpuHasAVX512VBMI2 = 0x40000; +static const int kCpuHasAVX512VBITALG = 0x80000; +static const int kCpuHasAVX512VPOPCNTDQ = 0x100000; // These flags are only valid on MIPS processors. -static const int kCpuHasMIPS = 0x10000; -static const int kCpuHasDSPR2 = 0x20000; -static const int kCpuHasMSA = 0x40000; +static const int kCpuHasMIPS = 0x200000; +static const int kCpuHasDSPR2 = 0x400000; +static const int kCpuHasMSA = 0x800000; // Optional init function. TestCpuFlag does an auto-init. // Returns cpu_info flags. diff --git a/include/libyuv/version.h b/include/libyuv/version.h index 9cb0c8c2c..a8d5f6d5f 100644 --- a/include/libyuv/version.h +++ b/include/libyuv/version.h @@ -11,6 +11,6 @@ #ifndef INCLUDE_LIBYUV_VERSION_H_ #define INCLUDE_LIBYUV_VERSION_H_ -#define LIBYUV_VERSION 1675 +#define LIBYUV_VERSION 1676 #endif // INCLUDE_LIBYUV_VERSION_H_ diff --git a/source/cpu_id.cc b/source/cpu_id.cc index d9bb9ec3b..7b979703d 100644 --- a/source/cpu_id.cc +++ b/source/cpu_id.cc @@ -242,10 +242,17 @@ static SAFEBUFFERS int GetCpuFlags(void) { // Detect AVX512bw if ((GetXCR0() & 0xe0) == 0xe0) { - cpu_info |= (cpu_info7[1] & 0x40000000) ? kCpuHasAVX3 : 0; + cpu_info |= (cpu_info7[1] & 0x40000000) ? kCpuHasAVX512BW : 0; + cpu_info |= (cpu_info7[1] & 0x80000000) ? kCpuHasAVX512VL : 0; + cpu_info |= (cpu_info7[2] & 0x00000002) ? kCpuHasAVX512VBMI: 0; + cpu_info |= (cpu_info7[2] & 0x00000040) ? kCpuHasAVX512VBMI2: 0; + cpu_info |= (cpu_info7[2] & 0x00001000) ? kCpuHasAVX512VBITALG: 0; + cpu_info |= (cpu_info7[2] & 0x00004000) ? kCpuHasAVX512VPOPCNTDQ: 0; + cpu_info |= (cpu_info7[2] & 0x00000100) ? kCpuHasGFNI: 0; } } + // TODO(fbarchard): Consider moving these to gtest // Environment variable overrides for testing. if (TestEnv("LIBYUV_DISABLE_X86")) { cpu_info &= ~kCpuHasX86; @@ -274,12 +281,12 @@ static SAFEBUFFERS int GetCpuFlags(void) { if (TestEnv("LIBYUV_DISABLE_FMA3")) { cpu_info &= ~kCpuHasFMA3; } - if (TestEnv("LIBYUV_DISABLE_AVX3")) { - cpu_info &= ~kCpuHasAVX3; - } if (TestEnv("LIBYUV_DISABLE_F16C")) { cpu_info &= ~kCpuHasF16C; } + if (TestEnv("LIBYUV_DISABLE_AVX512BW")) { + cpu_info &= ~kCpuHasAVX512BW; + } #endif #if defined(__mips__) && defined(__linux__) diff --git a/unit_test/cpu_test.cc b/unit_test/cpu_test.cc index c0b8910a1..8115e0dda 100644 --- a/unit_test/cpu_test.cc +++ b/unit_test/cpu_test.cc @@ -21,38 +21,55 @@ namespace libyuv { TEST_F(LibYUVBaseTest, TestCpuHas) { int cpu_flags = TestCpuFlag(-1); printf("Cpu Flags %x\n", cpu_flags); +#if defined(__arm__) || defined(__aarch64__) int has_arm = TestCpuFlag(kCpuHasARM); printf("Has ARM %x\n", has_arm); int has_neon = TestCpuFlag(kCpuHasNEON); printf("Has NEON %x\n", has_neon); +#endif int has_x86 = TestCpuFlag(kCpuHasX86); - printf("Has X86 %x\n", has_x86); int has_sse2 = TestCpuFlag(kCpuHasSSE2); - printf("Has SSE2 %x\n", has_sse2); int has_ssse3 = TestCpuFlag(kCpuHasSSSE3); - printf("Has SSSE3 %x\n", has_ssse3); int has_sse41 = TestCpuFlag(kCpuHasSSE41); - printf("Has SSE4.1 %x\n", has_sse41); int has_sse42 = TestCpuFlag(kCpuHasSSE42); - printf("Has SSE4.2 %x\n", has_sse42); int has_avx = TestCpuFlag(kCpuHasAVX); - printf("Has AVX %x\n", has_avx); int has_avx2 = TestCpuFlag(kCpuHasAVX2); - printf("Has AVX2 %x\n", has_avx2); int has_erms = TestCpuFlag(kCpuHasERMS); - printf("Has ERMS %x\n", has_erms); int has_fma3 = TestCpuFlag(kCpuHasFMA3); + int has_f16c = TestCpuFlag(kCpuHasF16C); + int has_gfni = TestCpuFlag(kCpuHasGFNI); + int has_avx512bw = TestCpuFlag(kCpuHasAVX512BW); + int has_avx512vl = TestCpuFlag(kCpuHasAVX512VL); + int has_avx512vbmi = TestCpuFlag(kCpuHasAVX512VBMI); + int has_avx512vbmi2 = TestCpuFlag(kCpuHasAVX512VBMI2); + int has_avx512vbitalg = TestCpuFlag(kCpuHasAVX512VBITALG); + int has_avx512vpopcntdq = TestCpuFlag(kCpuHasAVX512VPOPCNTDQ); + printf("Has X86 %x\n", has_x86); + printf("Has SSE2 %x\n", has_sse2); + printf("Has SSSE3 %x\n", has_ssse3); + printf("Has SSE4.1 %x\n", has_sse41); + printf("Has SSE4.2 %x\n", has_sse42); + printf("Has AVX %x\n", has_avx); + printf("Has AVX2 %x\n", has_avx2); + printf("Has ERMS %x\n", has_erms); printf("Has FMA3 %x\n", has_fma3); - int has_avx3 = TestCpuFlag(kCpuHasAVX3); - printf("Has AVX3 %x\n", has_avx3); - int has_f16c = TestCpuFlag(kCpuHasF16C); printf("Has F16C %x\n", has_f16c); + printf("Has GFNI %x\n", has_gfni); + printf("Has AVX512BW %x\n", has_avx512bw); + printf("Has AVX512VL %x\n", has_avx512vl); + printf("Has AVX512VBMI %x\n", has_avx512vbmi); + printf("Has AVX512VBMI2 %x\n", has_avx512vbmi2); + printf("Has AVX512VBITALG %x\n", has_avx512vbitalg); + printf("Has AVX512VPOPCNTDQ %x\n", has_avx512vpopcntdq); + +#if defined(__mips__) int has_mips = TestCpuFlag(kCpuHasMIPS); printf("Has MIPS %x\n", has_mips); int has_dspr2 = TestCpuFlag(kCpuHasDSPR2); printf("Has DSPR2 %x\n", has_dspr2); int has_msa = TestCpuFlag(kCpuHasMSA); printf("Has MSA %x\n", has_msa); +#endif } TEST_F(LibYUVBaseTest, TestCpuCompilerEnabled) { diff --git a/util/cpuid.c b/util/cpuid.c index 1e007a3e5..9ff618e0d 100644 --- a/util/cpuid.c +++ b/util/cpuid.c @@ -79,20 +79,32 @@ int main(int argc, const char* argv[]) { int has_sse42 = TestCpuFlag(kCpuHasSSE42); int has_avx = TestCpuFlag(kCpuHasAVX); int has_avx2 = TestCpuFlag(kCpuHasAVX2); - int has_avx3 = TestCpuFlag(kCpuHasAVX3); int has_erms = TestCpuFlag(kCpuHasERMS); int has_fma3 = TestCpuFlag(kCpuHasFMA3); - int has_f16c = TestCpuFlag(kCpuHasF16C); + int has_f16c = TestCpuFlag(kCpuHasF16C); + int has_gfni = TestCpuFlag(kCpuHasGFNI); + int has_avx512bw = TestCpuFlag(kCpuHasAVX512BW); + int has_avx512vl = TestCpuFlag(kCpuHasAVX512VL); + int has_avx512vbmi = TestCpuFlag(kCpuHasAVX512VBMI); + int has_avx512vbmi2 = TestCpuFlag(kCpuHasAVX512VBMI2); + int has_avx512vbitalg = TestCpuFlag(kCpuHasAVX512VBITALG); + int has_avx512vpopcntdq = TestCpuFlag(kCpuHasAVX512VPOPCNTDQ); printf("Has SSE2 %x\n", has_sse2); printf("Has SSSE3 %x\n", has_ssse3); printf("Has SSE4.1 %x\n", has_sse41); printf("Has SSE4.2 %x\n", has_sse42); printf("Has AVX %x\n", has_avx); printf("Has AVX2 %x\n", has_avx2); - printf("Has AVX3 %x\n", has_avx3); printf("Has ERMS %x\n", has_erms); printf("Has FMA3 %x\n", has_fma3); printf("Has F16C %x\n", has_f16c); + printf("Has GFNI %x\n", has_gfni); + printf("Has AVX512BW %x\n", has_avx512bw); + printf("Has AVX512VL %x\n", has_avx512vl); + printf("Has AVX512VBMI %x\n", has_avx512vbmi); + printf("Has AVX512VBMI2 %x\n", has_avx512vbmi2); + printf("Has AVX512VBITALG %x\n", has_avx512vbitalg); + printf("Has AVX512VPOPCNTDQ %x\n", has_avx512vpopcntdq); } return 0; }