Skip to content

Commit

Permalink
[X86] Update CPU detection to only enable XSAVE features if the OS ha…
Browse files Browse the repository at this point in the history
…s enabled them and the saving of YMM state. This seems to be consistent with gcc behavior.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250269 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
topperc committed Oct 14, 2015
1 parent 32e9bba commit 01e582a
Showing 1 changed file with 16 additions and 14 deletions.
30 changes: 16 additions & 14 deletions lib/Support/Host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -769,20 +769,22 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["movbe"] = (ECX >> 22) & 1;
Features["popcnt"] = (ECX >> 23) & 1;
Features["aes"] = (ECX >> 25) & 1;
Features["xsave"] = (ECX >> 26) & 1;
Features["rdrnd"] = (ECX >> 30) & 1;

// If CPUID indicates support for XSAVE, XRESTORE and AVX, and XGETBV
// indicates that the AVX registers will be saved and restored on context
// switch, then we have full AVX support.
bool HasAVX = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
!GetX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
Features["avx"] = HasAVX;
Features["fma"] = HasAVX && (ECX >> 12) & 1;
Features["f16c"] = HasAVX && (ECX >> 29) & 1;
bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) &&
!GetX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6);
Features["avx"] = HasAVXSave;
Features["fma"] = HasAVXSave && (ECX >> 12) & 1;
Features["f16c"] = HasAVXSave && (ECX >> 29) & 1;

// Only enable XSAVE if OS has enabled support for saving YMM state.
Features["xsave"] = HasAVXSave && (ECX >> 26) & 1;

// AVX512 requires additional context to be saved by the OS.
bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0);
bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0);

unsigned MaxExtLevel;
GetX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX);
Expand All @@ -792,15 +794,15 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["lzcnt"] = HasExtLeaf1 && ((ECX >> 5) & 1);
Features["sse4a"] = HasExtLeaf1 && ((ECX >> 6) & 1);
Features["prfchw"] = HasExtLeaf1 && ((ECX >> 8) & 1);
Features["xop"] = HasAVX && HasExtLeaf1 && ((ECX >> 11) & 1);
Features["fma4"] = HasAVX && HasExtLeaf1 && ((ECX >> 16) & 1);
Features["xop"] = HasExtLeaf1 && ((ECX >> 11) & 1) && HasAVXSave;
Features["fma4"] = HasExtLeaf1 && ((ECX >> 16) & 1) && HasAVXSave;
Features["tbm"] = HasExtLeaf1 && ((ECX >> 21) & 1);

bool HasLeaf7 = MaxLevel >= 7 &&
!GetX86CpuIDAndInfoEx(0x7, 0x0, &EAX, &EBX, &ECX, &EDX);

// AVX2 is only supported if we have the OS save support from AVX.
Features["avx2"] = HasAVX && HasLeaf7 && (EBX >> 5) & 1;
Features["avx2"] = HasAVXSave && HasLeaf7 && ((EBX >> 5) & 1);

Features["fsgsbase"] = HasLeaf7 && ((EBX >> 0) & 1);
Features["bmi"] = HasLeaf7 && ((EBX >> 3) & 1);
Expand All @@ -820,13 +822,13 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
Features["avx512bw"] = HasLeaf7 && ((EBX >> 30) & 1) && HasAVX512Save;
Features["avx512vl"] = HasLeaf7 && ((EBX >> 31) & 1) && HasAVX512Save;


bool HasLeafD = MaxLevel >= 0xd &&
!GetX86CpuIDAndInfoEx(0xd, 0x1, &EAX, &EBX, &ECX, &EDX);

Features["xsaveopt"] = Features["xsave"] && HasLeafD && ((EAX >> 0) & 1);
Features["xsavec"] = Features["xsave"] && HasLeafD && ((EAX >> 1) & 1);
Features["xsaves"] = Features["xsave"] && HasLeafD && ((EAX >> 3) & 1);
// Only enable XSAVE if OS has enabled support for saving YMM state.
Features["xsaveopt"] = HasAVXSave && HasLeafD && ((EAX >> 0) & 1);
Features["xsavec"] = HasAVXSave && HasLeafD && ((EAX >> 1) & 1);
Features["xsaves"] = HasAVXSave && HasLeafD && ((EAX >> 3) & 1);

return true;
}
Expand Down

0 comments on commit 01e582a

Please sign in to comment.