Skip to content

Commit d1603c3

Browse files
topperctru
authored andcommitted
[X86] Workaround possible CPUID bug in Sandy Bridge.
Don't access leaf 7 subleaf 1 unless subleaf 0 says it is supported via EAX. Intel documentation says invalid subleaves return 0. We had been relying on that behavior instead of checking the max sublef number. It appears that some Sandy Bridge CPUs return at least the subleaf 0 EDX value for subleaf 1. Best guess is that this is a bug in a microcode patch since all of the bits we're seeing set in EDX were introduced after Sandy Bridge was originally released. This is causing avxvnniint16 to be incorrectly enabled with -march=native on these CPUs. Reviewed By: pengfei, anna Differential Revision: https://reviews.llvm.org/D156963 (cherry picked from commit 2a5e3f4)
1 parent 51a4700 commit d1603c3

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

compiler-rt/lib/builtins/cpu_model.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,8 +751,11 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
751751
if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save)
752752
setFeature(FEATURE_AVX512VP2INTERSECT);
753753

754+
// EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
755+
// return all 0s for invalid subleaves so check the limit.
754756
bool HasLeaf7Subleaf1 =
755-
MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
757+
HasLeaf7 && EAX >= 1 &&
758+
!getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
756759
if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save)
757760
setFeature(FEATURE_AVX512BF16);
758761

llvm/lib/TargetParser/Host.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,8 +1241,11 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
12411241
if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save)
12421242
setFeature(X86::FEATURE_AVX512VP2INTERSECT);
12431243

1244+
// EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
1245+
// return all 0s for invalid subleaves so check the limit.
12441246
bool HasLeaf7Subleaf1 =
1245-
MaxLeaf >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1247+
HasLeaf7 && EAX >= 1 &&
1248+
!getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
12461249
if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save)
12471250
setFeature(X86::FEATURE_AVX512BF16);
12481251

@@ -1750,8 +1753,11 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
17501753
Features["avx512fp16"] = HasLeaf7 && ((EDX >> 23) & 1) && HasAVX512Save;
17511754
Features["amx-tile"] = HasLeaf7 && ((EDX >> 24) & 1) && HasAMXSave;
17521755
Features["amx-int8"] = HasLeaf7 && ((EDX >> 25) & 1) && HasAMXSave;
1756+
// EAX from subleaf 0 is the maximum subleaf supported. Some CPUs don't
1757+
// return all 0s for invalid subleaves so check the limit.
17531758
bool HasLeaf7Subleaf1 =
1754-
MaxLevel >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
1759+
HasLeaf7 && EAX >= 1 &&
1760+
!getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX);
17551761
Features["sha512"] = HasLeaf7Subleaf1 && ((EAX >> 0) & 1);
17561762
Features["sm3"] = HasLeaf7Subleaf1 && ((EAX >> 1) & 1);
17571763
Features["sm4"] = HasLeaf7Subleaf1 && ((EAX >> 2) & 1);

0 commit comments

Comments
 (0)