[clang] 3d3ad01 - [Clang][AArch64] set default mtune for macOS (#179136)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Feb 18 02:57:20 PST 2026
Author: Tomer Shafir
Date: 2026-02-18T12:57:16+02:00
New Revision: 3d3ad01e47abe63c78bf7ed58bc60b8ec45c6e25
URL: https://github.com/llvm/llvm-project/commit/3d3ad01e47abe63c78bf7ed58bc60b8ec45c6e25
DIFF: https://github.com/llvm/llvm-project/commit/3d3ad01e47abe63c78bf7ed58bc60b8ec45c6e25.diff
LOG: [Clang][AArch64] set default mtune for macOS (#179136)
This patch sets a default tune-cpu on macOS targets to `apple-m5`.
The implementation adds a helper in
`clang/lib/Driver/ToolChains/Arch/AArch64.h` called by
`clang/lib/Driver/ToolChains/Clang.cpp`. It doesnt follow a "check then
get" flow because its very concise, and returns an optional instead. It
adds a missing test file for mtune on Apple macOS targets, including the
new logic.
Added:
clang/test/Driver/aarch64-mtune-apple-macos.c
Modified:
clang/lib/Driver/ToolChains/Arch/AArch64.cpp
clang/lib/Driver/ToolChains/Arch/AArch64.h
clang/lib/Driver/ToolChains/Clang.cpp
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index cfc7cdfe0aedb..93fdbd17d1a43 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -97,6 +97,45 @@ std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
return getAArch64TargetCPUByTriple(Triple);
}
+/// \return the target tune CPU LLVM name based on the target triple.
+static std::optional<std::string>
+getAArch64TargetTuneCPUByTriple(const llvm::Triple &Triple) {
+ // Apple Silicon macs default to the latest available target for tuning.
+ if (Triple.isTargetMachineMac() && Triple.getArch() == llvm::Triple::aarch64)
+ return "apple-m5";
+
+ return std::nullopt;
+}
+
+/// \return the LLVM name of the AArch64 tune CPU we should target.
+/// Returns std::nullopt if no tune CPU should be specified.
+///
+/// Note: Unlike getAArch64TargetCPU, this function does not resolve CPU
+/// aliases, as it is currently not used for target architecture feature
+/// collection, but defers it to the backend.
+std::optional<std::string>
+aarch64::getAArch64TargetTuneCPU(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple) {
+ // -mtune has highest priority, then -mcpu
+ if (Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
+ StringRef Mtune = A->getValue();
+ std::string TuneCPU = Mtune.lower();
+
+ if (TuneCPU == "native")
+ return std::string(llvm::sys::getHostCPUName());
+
+ return TuneCPU;
+ }
+
+ // If -mcpu is present, let the backend mirror it for tuning
+ if (Args.getLastArg(options::OPT_mcpu_EQ))
+ return std::nullopt;
+
+ // If both -mtune and -mcpu are not present, try infer tune CPU from the
+ // target triple, or let the backend mirror the inferred target CPU for tuning
+ return getAArch64TargetTuneCPUByTriple(Triple);
+}
+
// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
static bool DecodeAArch64Features(const Driver &D, StringRef text,
llvm::AArch64::ExtensionSet &Extensions) {
@@ -244,9 +283,10 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
success = getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args);
else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
success = getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args);
- else if (success && isCPUDeterminedByTriple(Triple))
- success = getAArch64MicroArchFeaturesFromMcpu(
- D, getAArch64TargetCPUByTriple(Triple), Args);
+ else if (success) {
+ if (auto TuneCPU = getAArch64TargetTuneCPUByTriple(Triple))
+ success = getAArch64MicroArchFeaturesFromMtune(D, *TuneCPU, Args);
+ }
if (!success) {
auto Diag = D.Diag(diag::err_drv_unsupported_option_argument);
diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.h b/clang/lib/Driver/ToolChains/Arch/AArch64.h
index 97ebfa61a0f0d..8a1ac27d1aefd 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.h
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.h
@@ -12,6 +12,7 @@
#include "clang/Driver/Driver.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Option/Option.h"
+#include <optional>
#include <string>
#include <vector>
@@ -28,6 +29,10 @@ void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple,
std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args,
const llvm::Triple &Triple, llvm::opt::Arg *&A);
+std::optional<std::string>
+getAArch64TargetTuneCPU(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple);
+
bool isAArch64BareMetal(const llvm::Triple &Triple);
} // end namespace aarch64
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 5c5ed03e4dcd8..8aa2c595e2dea 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "Clang.h"
+#include "Arch/AArch64.h"
#include "Arch/ARM.h"
#include "Arch/LoongArch.h"
#include "Arch/Mips.h"
@@ -1688,12 +1689,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
AddAAPCSVolatileBitfieldArgs(Args, CmdArgs);
- if (const Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
+ if (auto TuneCPU = aarch64::getAArch64TargetTuneCPU(Args, Triple)) {
CmdArgs.push_back("-tune-cpu");
- if (strcmp(A->getValue(), "native") == 0)
- CmdArgs.push_back(Args.MakeArgString(llvm::sys::getHostCPUName()));
- else
- CmdArgs.push_back(A->getValue());
+ CmdArgs.push_back(Args.MakeArgString(*TuneCPU));
}
AddUnalignedAccessWarning(CmdArgs);
diff --git a/clang/test/Driver/aarch64-mtune-apple-macos.c b/clang/test/Driver/aarch64-mtune-apple-macos.c
new file mode 100644
index 0000000000000..f5992a2d63b7b
--- /dev/null
+++ b/clang/test/Driver/aarch64-mtune-apple-macos.c
@@ -0,0 +1,28 @@
+// Test -mtune flag on Apple Silicon AArch64 macOS.
+
+// Test default -mtune on macOS
+// RUN: %clang -### -c --target=arm64-apple-macos %s 2>&1 | FileCheck %s --check-prefixes=CPU-MACOS-DEFAULT,TUNE-MACOS-DEFAULT
+
+// RUN: %clang -### -c --target=arm64-apple-macos %s -mtune=generic 2>&1 | FileCheck %s --check-prefixes=CPU-MACOS-DEFAULT,TUNE-GENERIC
+
+// RUN: %clang -### -c --target=arm64-apple-macos %s -mtune=apple-m5 2>&1 | FileCheck %s --check-prefixes=CPU-MACOS-DEFAULT,TUNE-APPLE-M5
+
+// Check interaction between march and mtune.
+
+// RUN: %clang -### -c --target=arm64-apple-macos %s -march=armv8-a 2>&1 | FileCheck %s --check-prefixes=CPU-MACOS-DEFAULT,TUNE-MACOS-DEFAULT
+
+// RUN: %clang -### -c --target=arm64-apple-macos %s -march=armv8-a -mtune=apple-m5 2>&1 | FileCheck %s --check-prefixes=CPU-MACOS-DEFAULT,TUNE-APPLE-M5
+
+// Check interaction between mcpu and mtune.
+
+// RUN: %clang -### -c --target=arm64-apple-macos %s -mcpu=apple-m4 2>&1 | FileCheck %s --check-prefixes=CPU-APPLE-M4,NO-TUNE
+
+// RUN: %clang -### -c --target=arm64-apple-macos %s -mcpu=apple-m4 -mtune=apple-m5 2>&1 | FileCheck %s --check-prefixes=CPU-APPLE-M4,TUNE-APPLE-M5
+
+// CPU-MACOS-DEFAULT: "-target-cpu" "apple-m1"
+// CPU-APPLE-M4: "-target-cpu" "apple-m4"
+
+// TUNE-MACOS-DEFAULT: "-tune-cpu" "apple-m5"
+// TUNE-APPLE-M5: "-tune-cpu" "apple-m5"
+// TUNE-GENERIC: "-tune-cpu" "generic"
+// NO-TUNE-NOT: "-tune-cpu"
More information about the cfe-commits
mailing list