[llvm-branch-commits] [clang] [AArch64][clang] Improve -mcpu= and -mtune= error messages too (PR #197640)
Jonathan Thackray via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu May 14 03:01:33 PDT 2026
https://github.com/jthackray updated https://github.com/llvm/llvm-project/pull/197640
>From 0b53f85443dec9993bdad33f6f928469e55f8805 Mon Sep 17 00:00:00 2001
From: Jonathan Thackray <jonathan.thackray at arm.com>
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='
More information about the llvm-branch-commits
mailing list