Skip to content

Commit 88c6773

Browse files
oontvootstellar
authored andcommitted
Reland 293e8fa
[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 New change: - Surround usages of x86 helper in llvm-exegesis/X86/Target.cpp with ifdef - Fix bug which caused the caller of getVendorSignature to not have a copy of EAX that it expected. (cherry picked from commit f8b01d5)
1 parent 0eae129 commit 88c6773

File tree

3 files changed

+85
-16
lines changed

3 files changed

+85
-16
lines changed

llvm/include/llvm/Support/Host.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,20 @@ namespace sys {
6565
StringRef getHostCPUNameForARM(StringRef ProcCpuinfoContent);
6666
StringRef getHostCPUNameForS390x(StringRef ProcCpuinfoContent);
6767
StringRef getHostCPUNameForBPF();
68+
69+
/// Helper functions to extract CPU details from CPUID on x86.
70+
namespace x86 {
71+
enum class VendorSignatures {
72+
UNKNOWN,
73+
GENUINE_INTEL,
74+
AUTHENTIC_AMD,
75+
};
76+
77+
/// Returns the host CPU's vendor.
78+
/// MaxLeaf: if a non-nullptr pointer is specified, the EAX value will be
79+
/// assigned to its pointee.
80+
VendorSignatures getVendorSignature(unsigned *MaxLeaf = nullptr);
81+
} // namespace x86
6882
}
6983
}
7084
}

llvm/lib/Support/Host.cpp

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -417,11 +417,6 @@ StringRef sys::detail::getHostCPUNameForBPF() {
417417
#if defined(__i386__) || defined(_M_IX86) || \
418418
defined(__x86_64__) || defined(_M_X64)
419419

420-
enum VendorSignatures {
421-
SIG_INTEL = 0x756e6547 /* Genu */,
422-
SIG_AMD = 0x68747541 /* Auth */
423-
};
424-
425420
// The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max).
426421
// Check motivated by bug reports for OpenSSL crashing on CPUs without CPUID
427422
// support. Consequently, for i386, the presence of CPUID is checked first
@@ -495,6 +490,42 @@ static bool getX86CpuIDAndInfo(unsigned value, unsigned *rEAX, unsigned *rEBX,
495490
#endif
496491
}
497492

493+
namespace llvm {
494+
namespace sys {
495+
namespace detail {
496+
namespace x86 {
497+
498+
VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
499+
unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
500+
if (MaxLeaf == nullptr)
501+
MaxLeaf = &EAX;
502+
else
503+
*MaxLeaf = 0;
504+
505+
if (!isCpuIdSupported())
506+
return VendorSignatures::UNKNOWN;
507+
508+
if (getX86CpuIDAndInfo(0, MaxLeaf, &EBX, &ECX, &EDX) || *MaxLeaf < 1)
509+
return VendorSignatures::UNKNOWN;
510+
511+
// "Genu ineI ntel"
512+
if (EBX == 0x756e6547 && ECX == 0x6c65746e && EDX == 0x49656e69)
513+
return VendorSignatures::GENUINE_INTEL;
514+
515+
// "Auth enti cAMD"
516+
if (EBX == 0x68747541 && ECX == 0x69746e65 && EDX == 0x444d4163)
517+
return VendorSignatures::AUTHENTIC_AMD;
518+
519+
return VendorSignatures::UNKNOWN;
520+
}
521+
522+
} // namespace x86
523+
} // namespace detail
524+
} // namespace sys
525+
} // namespace llvm
526+
527+
using namespace llvm::sys::detail::x86;
528+
498529
/// getX86CpuIDAndInfoEx - Execute the specified cpuid with subleaf and return
499530
/// the 4 values in the specified arguments. If we can't run cpuid on the host,
500531
/// return true.
@@ -1092,14 +1123,12 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf,
10921123
}
10931124

10941125
StringRef sys::getHostCPUName() {
1095-
unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
1096-
unsigned MaxLeaf, Vendor;
1097-
1098-
if (!isCpuIdSupported())
1126+
unsigned MaxLeaf = 0;
1127+
const VendorSignatures Vendor = getVendorSignature(&MaxLeaf);
1128+
if (Vendor == VendorSignatures::UNKNOWN)
10991129
return "generic";
11001130

1101-
if (getX86CpuIDAndInfo(0, &MaxLeaf, &Vendor, &ECX, &EDX) || MaxLeaf < 1)
1102-
return "generic";
1131+
unsigned EAX = 0, EBX = 0, ECX = 0, EDX = 0;
11031132
getX86CpuIDAndInfo(0x1, &EAX, &EBX, &ECX, &EDX);
11041133

11051134
unsigned Family = 0, Model = 0;
@@ -1114,10 +1143,10 @@ StringRef sys::getHostCPUName() {
11141143

11151144
StringRef CPU;
11161145

1117-
if (Vendor == SIG_INTEL) {
1146+
if (Vendor == VendorSignatures::GENUINE_INTEL) {
11181147
CPU = getIntelProcessorTypeAndSubtype(Family, Model, Features, &Type,
11191148
&Subtype);
1120-
} else if (Vendor == SIG_AMD) {
1149+
} else if (Vendor == VendorSignatures::AUTHENTIC_AMD) {
11211150
CPU = getAMDProcessorTypeAndSubtype(Family, Model, Features, &Type,
11221151
&Subtype);
11231152
}
@@ -1219,6 +1248,19 @@ StringRef sys::getHostCPUName() {
12191248
}
12201249
#else
12211250
StringRef sys::getHostCPUName() { return "generic"; }
1251+
namespace llvm {
1252+
namespace sys {
1253+
namespace detail {
1254+
namespace x86 {
1255+
1256+
VendorSignatures getVendorSignature(unsigned *MaxLeaf) {
1257+
return VendorSignatures::UNKNOWN;
1258+
}
1259+
1260+
} // namespace x86
1261+
} // namespace detail
1262+
} // namespace sys
1263+
} // namespace llvm
12221264
#endif
12231265

12241266
#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))

llvm/tools/llvm-exegesis/lib/X86/Target.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "llvm/Support/Errc.h"
2323
#include "llvm/Support/Error.h"
2424
#include "llvm/Support/FormatVariadic.h"
25+
#include "llvm/Support/Host.h"
2526

2627
#include <memory>
2728
#include <string>
@@ -727,13 +728,25 @@ class ExegesisX86Target : public ExegesisTarget {
727728

728729
#if defined(__linux__) && defined(HAVE_LIBPFM) && \
729730
defined(LIBPFM_HAS_FIELD_CYCLES)
730-
// If the kernel supports it, the hardware still may not have it.
731-
return X86LbrCounter::checkLbrSupport();
731+
// FIXME: Fix this.
732+
// https://bugs.llvm.org/show_bug.cgi?id=48918
733+
// For now, only do the check if we see an Intel machine because
734+
// the counter uses some intel-specific magic and it could
735+
// be confuse and think an AMD machine actually has LBR support.
736+
#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || \
737+
defined(_M_X64)
738+
using namespace sys::detail::x86;
739+
740+
if (getVendorSignature() == VendorSignatures::GENUINE_INTEL)
741+
// If the kernel supports it, the hardware still may not have it.
742+
return X86LbrCounter::checkLbrSupport();
732743
#else
744+
llvm_unreachable("Running X86 exegesis on non-X86 target");
745+
#endif
746+
#endif
733747
return llvm::make_error<llvm::StringError>(
734748
"LBR not supported on this kernel and/or platform",
735749
llvm::errc::not_supported);
736-
#endif
737750
}
738751

739752
std::unique_ptr<SavedState> withSavedState() const override {

0 commit comments

Comments
 (0)