From 01e582a1d119bc448ef5ccb9b090fab7a698f752 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 14 Oct 2015 05:37:42 +0000 Subject: [PATCH] [X86] Update CPU detection to only enable XSAVE features if the OS has 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 --- lib/Support/Host.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp index da918898e2f..d7c9947b02d 100644 --- a/lib/Support/Host.cpp +++ b/lib/Support/Host.cpp @@ -769,20 +769,22 @@ bool sys::getHostCPUFeatures(StringMap &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); @@ -792,15 +794,15 @@ bool sys::getHostCPUFeatures(StringMap &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); @@ -820,13 +822,13 @@ bool sys::getHostCPUFeatures(StringMap &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; } -- 2.34.1