Skip to content

Commit

Permalink
Better messages on unknown CPU names. (#19902)
Browse files Browse the repository at this point in the history
Signed-off-by: Benoit Jacob <[email protected]>
  • Loading branch information
bjacob authored Feb 4, 2025
1 parent eb19497 commit a808900
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 26 deletions.
9 changes: 3 additions & 6 deletions compiler/plugins/target/LLVMCPU/LLVMTargetOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,12 +607,9 @@ LLVMTargetOptions LLVMCPUTargetCLOptions::getTargetOptions() {
ResolveCPUAndCPUFeaturesStatus status;
std::optional<LLVMTarget> maybeTarget = LLVMTarget::create(
targetTriple, targetCPU, targetCPUFeatures, linkEmbedded, status);
(void)status; // Ignore status here, since this code runs at target backend
// registration time and we don't know if this backend will
// actually be used, and these error statuses are non-fatal,
// mostly warning about fallbacks. If the target backend is
// actually used, any error here will also trigger in
// loadFromConfigAttr, where we will generate an IR error.
if (status != ResolveCPUAndCPUFeaturesStatus::OK) {
llvm::errs() << getMessage(status, targetTriple);
}
if (maybeTarget) {
targetOptions.target = *maybeTarget;
} else {
Expand Down
77 changes: 57 additions & 20 deletions compiler/plugins/target/LLVMCPU/ResolveCPUAndCPUFeatures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "compiler/plugins/target/LLVMCPU/ResolveCPUAndCPUFeatures.h"

#include "llvm/Support/FormatVariadic.h"
#include "llvm/TargetParser/AArch64TargetParser.h"
#include "llvm/TargetParser/Host.h"
#include "llvm/TargetParser/RISCVTargetParser.h"
Expand Down Expand Up @@ -49,21 +50,25 @@ resolveCPUFeaturesForCPU(const llvm::Triple &triple, std::string &cpu,
return ResolveCPUAndCPUFeaturesStatus::OK;
}
llvm::SubtargetFeatures targetCpuFeatures(cpuFeatures);
auto addCpuFeatures = [&](const auto &getFeaturesForCPU,
auto &cpuFeatureList) {
getFeaturesForCPU(cpu, cpuFeatureList, false);
for (const auto &feature : cpuFeatureList) {
if (triple.isX86()) {
if (!llvm::X86::parseArchX86(cpu, /*Only64Bit=*/true)) {
return ResolveCPUAndCPUFeaturesStatus::UnknownCPU;
}
llvm::SmallVector<llvm::StringRef> features;
llvm::X86::getFeaturesForCPU(cpu, features, /*NeedPlus=*/false);
for (const auto &feature : features) {
targetCpuFeatures.AddFeature(feature);
}
};
if (triple.isX86()) {
llvm::SmallVector<llvm::StringRef> cpuFeatureList;
addCpuFeatures(llvm::X86::getFeaturesForCPU, cpuFeatureList);
} else if (triple.isRISCV64()) {
llvm::SmallVector<std::string> cpuFeatureList;
addCpuFeatures(llvm::RISCV::getFeaturesForCPU, cpuFeatureList);
if (!llvm::RISCV::parseCPU(cpu, triple.isRISCV64())) {
return ResolveCPUAndCPUFeaturesStatus::UnknownCPU;
}
llvm::SmallVector<std::string> features;
llvm::RISCV::getFeaturesForCPU(cpu, features, /*NeedPlus=*/false);
for (const auto &feature : features) {
targetCpuFeatures.AddFeature(feature);
}
} else if (triple.isAArch64()) {
std::vector<llvm::StringRef> cpuFeatureList;
std::optional<llvm::AArch64::CpuInfo> cpuInfo =
llvm::AArch64::parseCpu(cpu);
if (!cpuInfo) {
Expand Down Expand Up @@ -147,18 +152,56 @@ In the rest of this message, these fields are referred to as just `cpu` and `cpu
return msg;
}

std::string getUnknownCPUMessage(std::string_view triple_str) {
llvm::Triple triple(triple_str);
std::string msg = llvm::formatv("Unknown CPU for target architecture {}.\n",
triple.getArchName());
if (triple.isX86()) {
msg += "List of accepted CPUs: ";
llvm::SmallVector<llvm::StringRef> allAcceptedCpus;
llvm::X86::fillValidCPUArchList(allAcceptedCpus, /*Only64Bit=*/true);
llvm::raw_string_ostream s(msg);
llvm::interleaveComma(allAcceptedCpus, s);
msg += "\n";
} else if (triple.isRISCV()) {
msg += "List of accepted CPUs: ";
llvm::SmallVector<llvm::StringRef> allAcceptedCpus;
llvm::RISCV::fillValidCPUArchList(allAcceptedCpus, /*IsRV64=*/true);
llvm::raw_string_ostream s(msg);
llvm::interleaveComma(allAcceptedCpus, s);
msg += "\n";
} else if (triple.isAArch64()) {
msg += "List of accepted CPUs: ";
llvm::SmallVector<llvm::StringRef> allAcceptedCpus;
llvm::AArch64::fillValidCPUArchList(allAcceptedCpus);
llvm::raw_string_ostream s(msg);
llvm::interleaveComma(allAcceptedCpus, s);
msg += "\n";
}
return msg;
}

} // namespace

ResolveCPUAndCPUFeaturesStatus
resolveCPUAndCPUFeatures(std::string_view triple_str, std::string &cpu,
std::string &cpuFeatures) {
// Helper to return the first non-OK status.
auto combine = [](ResolveCPUAndCPUFeaturesStatus a,
ResolveCPUAndCPUFeaturesStatus b) {
return a == ResolveCPUAndCPUFeaturesStatus::OK ? b : a;
};

llvm::Triple triple(triple_str);
// No early-return on error status. The caller may treat these errors as
// non-fatal and will carry on with whichever `cpu` and `cpuFeatures` we
// produce.
auto status1 = resolveHostCPUAndCPUFeatures(cpu, cpuFeatures);
auto status2 = resolveCPUFeaturesForCPU(triple, cpu, cpuFeatures);
tweakCPUFeatures(triple, cpu, cpuFeatures);
auto status12 = combine(status1, status2);
if (status12 == ResolveCPUAndCPUFeaturesStatus::OK) {
tweakCPUFeatures(triple, cpu, cpuFeatures);
}

std::string defaultTweakedCpu;
std::string defaultTweakedCpuFeatures;
Expand All @@ -169,13 +212,7 @@ resolveCPUAndCPUFeatures(std::string_view triple_str, std::string &cpu,
? ResolveCPUAndCPUFeaturesStatus::ImplicitGenericFallback
: ResolveCPUAndCPUFeaturesStatus::OK;

// Helper to return the first non-OK status.
auto combine = [](ResolveCPUAndCPUFeaturesStatus a,
ResolveCPUAndCPUFeaturesStatus b) {
return a == ResolveCPUAndCPUFeaturesStatus::OK ? b : a;
};

return combine(combine(status1, status2), status3);
return combine(status12, status3);
}

std::string getMessage(ResolveCPUAndCPUFeaturesStatus status,
Expand All @@ -191,7 +228,7 @@ std::string getMessage(ResolveCPUAndCPUFeaturesStatus status,
"target architecture. Pass explicit "
"CPU-features, or implement the missing mapping.\n";
case ResolveCPUAndCPUFeaturesStatus::UnknownCPU:
return "Unknown CPU name for this target architecture.";
return getUnknownCPUMessage(triple_str);
default:
assert(false);
return "";
Expand Down

0 comments on commit a808900

Please sign in to comment.