[llvm] 293e8fa - [llvm-exegesis] Disable the LBR check on AMD

Vy Nguyen via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 4 08:17:11 PST 2021


Author: Vy Nguyen
Date: 2021-03-04T11:16:38-05:00
New Revision: 293e8fa13d3f05e993771577a4c022deee5cbf6e

URL: https://github.com/llvm/llvm-project/commit/293e8fa13d3f05e993771577a4c022deee5cbf6e
DIFF: https://github.com/llvm/llvm-project/commit/293e8fa13d3f05e993771577a4c022deee5cbf6e.diff

LOG: [llvm-exegesis] Disable the LBR check on AMD

https://bugs.llvm.org/show_bug.cgi?id=48918

The bug reported a hang (or very very slow runtime) on a Zen2. Unfortunately, we don't have the hardware right now to debug it and I was not able to reproduce the bug on a HSW.
Theory we've got is that the lbr-checking code could be confused on AMD.

Differential Revision: https://reviews.llvm.org/D97504

Added: 
    

Modified: 
    llvm/include/llvm/Support/Host.h
    llvm/lib/Support/Host.cpp
    llvm/tools/llvm-exegesis/lib/X86/Target.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Support/Host.h b/llvm/include/llvm/Support/Host.h
index d4ef389450cc..3a7397edd530 100644
--- a/llvm/include/llvm/Support/Host.h
+++ b/llvm/include/llvm/Support/Host.h
@@ -65,6 +65,21 @@ namespace sys {
   StringRef getHostCPUNameForARM(StringRef ProcCpuinfoContent);
   StringRef getHostCPUNameForS390x(StringRef ProcCpuinfoContent);
   StringRef getHostCPUNameForBPF();
+
+  /// Helper functions to extract CPU details from CPUID on x86.
+#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) ||            \
+    defined(_M_X64)
+  namespace x86 {
+  enum class VendorSignatures {
+    UNKNOWN,
+    GENUINE_INTEL,
+    AUTHENTIC_AMD,
+  };
+
+  /// Returns the host CPU's vendor.
+  VendorSignatures getVendorSignature();
+  } // namespace x86
+#endif
   }
 }
 }

diff  --git a/llvm/lib/Support/Host.cpp b/llvm/lib/Support/Host.cpp
index d89518b74704..2b0451e89214 100644
--- a/llvm/lib/Support/Host.cpp
+++ b/llvm/lib/Support/Host.cpp
@@ -420,11 +420,6 @@ StringRef sys::detail::getHostCPUNameForBPF() {
 #if defined(__i386__) || defined(_M_IX86) || \
     defined(__x86_64__) || defined(_M_X64)
 
-enum VendorSignatures {
-  SIG_INTEL = 0x756e6547 /* Genu */,
-  SIG_AMD = 0x68747541 /* Auth */
-};
-
 // The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
 // Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
 // support. Consequently, for i386, the presence of CPUID is checked first
@@ -498,6 +493,38 @@ static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
 #endif
 }
 
+namespace llvm {
+namespace sys {
+namespace detail {
+namespace x86 {
+
+VendorSignatures getVendorSignature() {
+  unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
+
+  if (!isCpuIdSupported())
+    return VendorSignatures::UNKNOWN;
+
+  if (getX86CpuIDAndInfo(0, &EAX, &EBX, &ECX, &EDX) || EAX < 1)
+    return VendorSignatures::UNKNOWN;
+
+  // "Genu ineI ntel"
+  if (EBX == 0x756e6547 && ECX == 0x6c65746e && EDX == 0x49656e69)
+    return VendorSignatures::GENUINE_INTEL;
+
+  // "Auth enti cAMD"
+  if (EBX == 0x68747541 && ECX == 0x69746e65 && EDX == 0x444d4163)
+    return VendorSignatures::AUTHENTIC_AMD;
+
+  return VendorSignatures::UNKNOWN;
+}
+
+} // namespace x86
+} // namespace detail
+} // namespace sys
+} // namespace llvm
+
+using namespace llvm::sys::detail::x86;
+
 /// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
 /// the 4 values in the specified arguments.  If we can't run cpuid on the host,
 /// return true.
@@ -1095,18 +1122,16 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
 }
 
 StringRef sys::getHostCPUName() {
-  unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
-  unsigned MaxLeaf, Vendor;
-
-  if (!isCpuIdSupported())
+  const VendorSignatures Vendor = getVendorSignature();
+  if (Vendor == VendorSignatures::UNKNOWN)
     return "generic";
 
-  if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX) || MaxLeaf < 1)
-    return "generic";
+  unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
   getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
 
   unsigned Family = 0, Model = 0;
   unsigned Features[(X86::CPU_FEATURE_MAX + 31) / 32] = {0};
+  unsigned MaxLeaf = 0;
   detectX86FamilyModel(EAX, &Family, &Model);
   getAvailableFeatures(ECX, EDX, MaxLeaf, Features);
 
@@ -1117,10 +1142,10 @@ StringRef sys::getHostCPUName() {
 
   StringRef CPU;
 
-  if (Vendor == SIG_INTEL) {
+  if (Vendor == VendorSignatures::GENUINE_INTEL) {
     CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type,
                                           &Subtype);
-  } else if (Vendor == SIG_AMD) {
+  } else if (Vendor == VendorSignatures::AUTHENTIC_AMD) {
     CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type,
                                         &Subtype);
   }

diff  --git a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
index 96781dd807a8..67fb5d11cb4b 100644
--- a/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
+++ b/llvm/tools/llvm-exegesis/lib/X86/Target.cpp
@@ -22,6 +22,7 @@
 #include "llvm/Support/Errc.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/Host.h"
 
 #include <memory>
 #include <string>
@@ -735,6 +736,8 @@ class ExegesisX86Target : public ExegesisTarget {
   }
 
   Error checkFeatureSupport() const override {
+    using namespace sys::detail::x86;
+
     // LBR is the only feature we conditionally support now.
     // So if LBR is not requested, then we should be able to run the benchmarks.
     if (LbrSamplingPeriod == 0)
@@ -742,13 +745,18 @@ class ExegesisX86Target : public ExegesisTarget {
 
 #if defined(__linux__) && defined(HAVE_LIBPFM) &&                              \
     defined(LIBPFM_HAS_FIELD_CYCLES)
-    // If the kernel supports it, the hardware still may not have it.
-    return X86LbrCounter::checkLbrSupport();
-#else
+    // FIXME: Fix this.
+    // https://bugs.llvm.org/show_bug.cgi?id=48918
+    // For now, only do the check if we see an Intel machine because
+    // the counter uses some intel-specific magic and it could
+    // be confuse and think an AMD machine actually has LBR support.
+    if (getVendorSignature() == VendorSignatures::GENUINE_INTEL)
+      // If the kernel supports it, the hardware still may not have it.
+      return X86LbrCounter::checkLbrSupport();
+#endif
     return llvm::make_error<llvm::StringError>(
         "LBR not supported on this kernel and/or platform",
         llvm::errc::not_supported);
-#endif
   }
 
   std::unique_ptr<SavedState> withSavedState() const override {


        


More information about the llvm-commits mailing list