https://github.com/jthackray updated https://github.com/llvm/llvm-project/pull/197640
>From b85fb447b6afdb741bb4f3da46db1c33a9299856 Mon Sep 17 00:00:00 2001 From: Jonathan Thackray <[email protected]> Date: Wed, 13 May 2026 21:46:34 +0100 Subject: [PATCH] [AArch64][clang] Improve -mcpu= and -mtune= error messages too Similar to my previous change improving the error message for `-march=` in #197441, this changes `-mcpu=` and `-mtune=` arguments to only report the invalid feature flag, rather than the entire string. This is a much clearer error message for the user. --- clang/lib/Driver/ToolChains/Arch/AArch64.cpp | 60 +++++++++++--------- clang/test/Driver/aarch64-march.c | 13 +++++ 2 files changed, 47 insertions(+), 26 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp index f42465da14a71..7ed4002e53420 100644 --- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp +++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp @@ -137,10 +137,9 @@ aarch64::getAArch64TargetTuneCPU(const llvm::opt::ArgList &Args, } // Decode AArch64 features from string like +[no]featureA+[no]featureB+... -static bool -DecodeAArch64Features(const Driver &D, StringRef text, - llvm::AArch64::ExtensionSet &Extensions, - std::optional<std::string> *InvalidArg = nullptr) { +static bool DecodeAArch64Features(const Driver &D, StringRef text, + llvm::AArch64::ExtensionSet &Extensions, + std::optional<std::string> &InvalidArg) { SmallVector<StringRef, 8> Split; text.split(Split, StringRef("+"), -1, false); @@ -150,8 +149,7 @@ DecodeAArch64Features(const Driver &D, StringRef text, continue; } if (!Extensions.parseModifier(Feature)) { - if (InvalidArg) - InvalidArg->emplace(("+" + Feature).str()); + InvalidArg.emplace(("+" + Feature).str()); return false; } } @@ -180,7 +178,8 @@ static bool DecodeAArch64HostFeatures(llvm::AArch64::ExtensionSet &Extensions) { // Check if the CPU name and feature modifiers in -mcpu are legal. If yes, // decode CPU and feature. static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, - llvm::AArch64::ExtensionSet &Extensions) { + llvm::AArch64::ExtensionSet &Extensions, + std::optional<std::string> &InvalidArg) { std::pair<StringRef, StringRef> Split = Mcpu.split("+"); StringRef CPU = Split.first; const bool IsNative = CPU == "native"; @@ -190,8 +189,10 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, const std::optional<llvm::AArch64::CpuInfo> CpuInfo = llvm::AArch64::parseCpu(CPU); - if (!CpuInfo) + if (!CpuInfo) { + InvalidArg.emplace(Split.first.str()); return false; + } Extensions.addCPUDefaults(*CpuInfo); @@ -199,7 +200,7 @@ static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, return false; if (Split.second.size() && - !DecodeAArch64Features(D, Split.second, Extensions)) + !DecodeAArch64Features(D, Split.second, Extensions, InvalidArg)) return false; return true; @@ -214,7 +215,7 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March, std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+"); if (Split.first == "native") - return DecodeAArch64Mcpu(D, MarchLowerCase, Extensions); + return DecodeAArch64Mcpu(D, MarchLowerCase, Extensions, InvalidArg); const llvm::AArch64::ArchInfo *ArchInfo = llvm::AArch64::parseArch(Split.first); @@ -226,7 +227,7 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March, Extensions.addArchDefaults(*ArchInfo); if ((Split.second.size() && - !DecodeAArch64Features(D, Split.second, Extensions, &InvalidArg))) + !DecodeAArch64Features(D, Split.second, Extensions, InvalidArg))) return false; return true; @@ -235,23 +236,27 @@ getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March, static bool getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, const ArgList &Args, - llvm::AArch64::ExtensionSet &Extensions) { + llvm::AArch64::ExtensionSet &Extensions, + std::optional<std::string> &InvalidArg) { std::string McpuLowerCase = Mcpu.lower(); - return DecodeAArch64Mcpu(D, McpuLowerCase, Extensions); + return DecodeAArch64Mcpu(D, McpuLowerCase, Extensions, InvalidArg); } -static bool getAArch64MicroArchFeaturesFromMtune(const Driver &D, - StringRef Mtune, - const ArgList &Args) { +static bool +getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune, + const ArgList &Args, + std::optional<std::string> &InvalidArg) { // Check CPU name is valid, but ignore any extensions on it. std::string MtuneLowerCase = Mtune.lower(); llvm::AArch64::ExtensionSet Extensions; - return DecodeAArch64Mcpu(D, MtuneLowerCase, Extensions); + return DecodeAArch64Mcpu(D, MtuneLowerCase, Extensions, InvalidArg); } -static bool getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, - const ArgList &Args) { - return getAArch64MicroArchFeaturesFromMtune(D, Mcpu, Args); +static bool +getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, + const ArgList &Args, + std::optional<std::string> &InvalidArg) { + return getAArch64MicroArchFeaturesFromMtune(D, Mcpu, Args, InvalidArg); } void aarch64::getAArch64TargetFeatures(const Driver &D, @@ -280,23 +285,26 @@ void aarch64::getAArch64TargetFeatures(const Driver &D, success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Extensions, InvalidArg); else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) - success = - getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Extensions); + success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Extensions, + InvalidArg); else if (isCPUDeterminedByTriple(Triple)) success = getAArch64ArchFeaturesFromMcpu( - D, getAArch64TargetCPUByTriple(Triple), Args, Extensions); + D, getAArch64TargetCPUByTriple(Triple), Args, Extensions, InvalidArg); else // Default to 'A' profile if the architecture is not specified. success = getAArch64ArchFeaturesFromMarch(D, "armv8-a", Args, Extensions, InvalidArg); if (success && (A = Args.getLastArg(options::OPT_mtune_EQ))) - success = getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args); + success = getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, + InvalidArg); else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ))) - success = getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args); + success = + getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, InvalidArg); else if (success) { if (auto TuneCPU = getAArch64TargetTuneCPUByTriple(Triple)) - success = getAArch64MicroArchFeaturesFromMtune(D, *TuneCPU, Args); + success = + getAArch64MicroArchFeaturesFromMtune(D, *TuneCPU, Args, InvalidArg); } if (!success) { diff --git a/clang/test/Driver/aarch64-march.c b/clang/test/Driver/aarch64-march.c index d2cea0e50def3..5a0dba3a7e7b7 100644 --- a/clang/test/Driver/aarch64-march.c +++ b/clang/test/Driver/aarch64-march.c @@ -36,3 +36,16 @@ // INVALID-EXT: error: unsupported argument '+badfeature' to option '-march=' // INVALID-EXT-NOT: armv9.6-a+sme2+sme2p1+sve2+sve2p1+badfeature+aes+sha2+memtag+bf16 // INVALID-ARCH: error: unsupported argument 'notanarch' to option '-march=' + +// ================== Check whether -mcpu diagnoses the first invalid argument. +// RUN: not %clang --target=aarch64 -mcpu=generic+sme2+badfeature+aes %s -### -c 2>&1 | FileCheck -check-prefix=INVALID-MCPU-EXT %s +// RUN: not %clang --target=aarch64 -mcpu=notacpu+sme2 %s -### -c 2>&1 | FileCheck -check-prefix=INVALID-MCPU %s +// INVALID-MCPU-EXT: error: unsupported argument '+badfeature' to option '-mcpu=' +// INVALID-MCPU-EXT-NOT: generic+sme2+badfeature+aes +// INVALID-MCPU: error: unsupported argument 'notacpu' to option '-mcpu=' + +// ================== Check whether -mtune diagnoses the first invalid argument. +// RUN: not %clang --target=aarch64 -mtune=generic+sme2+badfeature+aes %s -### -c 2>&1 | FileCheck -check-prefix=INVALID-MTUNE-EXT %s +// RUN: not %clang --target=aarch64 -mtune=notacpu+sme2 %s -### -c 2>&1 | FileCheck -check-prefix=INVALID-MTUNE %s +// INVALID-MTUNE-EXT: error: unsupported argument '+badfeature' to option '-mtune=' +// INVALID-MTUNE: error: unsupported argument 'notacpu' to option '-mtune=' _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
