Check for BMI2 support before enabling AVX2 code paths

With MSVC, compiling with AVX2 support will also result in the
generation of BMI2 instructions. Some early Haswell CPUs reportedly support AVX2 but not BMI2. We have seen crashes (illegal instruction)
on these CPUs in our AVX2 code paths on MULX instructions (part of BMI2).

Including a check for BMI2 when checking for AVX2 support is
expected to solve the issue.

Please see the bug referenced below for more background on this issue.

Bug: chromium:1315519
Change-Id: I3a0a9838f1f632704ba505ecbb81a6f8b1889319
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/260323
Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Reviewed-by: Henrik Andreasson <henrika@google.com>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36701}
This commit is contained in:
Gustaf Ullberg 2022-04-29 08:54:29 +02:00 committed by WebRTC LUCI CQ
parent 9c83d9d99e
commit 8b8d0b5eac

View File

@ -93,13 +93,14 @@ int GetCPUInfo(CPUFeature feature) {
// a) AVX are supported by the CPU, // a) AVX are supported by the CPU,
// b) XSAVE is supported by the CPU, // b) XSAVE is supported by the CPU,
// c) XSAVE is enabled by the kernel. // c) XSAVE is enabled by the kernel.
// See http://software.intel.com/en-us/blogs/2011/04/14/is-avx-enabled // Compiling with MSVC and /arch:AVX2 surprisingly generates BMI2
// AVX2 support needs (avx_support && (cpu_info7[1] & 0x00000020) != 0;). // instructions (see crbug.com/1315519).
return (cpu_info[2] & 0x10000000) != 0 && return (cpu_info[2] & 0x10000000) != 0 /* AVX */ &&
(cpu_info[2] & 0x04000000) != 0 /* XSAVE */ && (cpu_info[2] & 0x04000000) != 0 /* XSAVE */ &&
(cpu_info[2] & 0x08000000) != 0 /* OSXSAVE */ && (cpu_info[2] & 0x08000000) != 0 /* OSXSAVE */ &&
(xgetbv(0) & 0x00000006) == 6 /* XSAVE enabled by kernel */ && (xgetbv(0) & 0x00000006) == 6 /* XSAVE enabled by kernel */ &&
(cpu_info7[1] & 0x00000020) != 0; (cpu_info7[1] & 0x00000020) != 0 /* AVX2 */ &&
(cpu_info7[1] & 0x00000100) != 0 /* BMI2 */;
} }
#endif // WEBRTC_ENABLE_AVX2 #endif // WEBRTC_ENABLE_AVX2
return 0; return 0;