-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[AArch64] Bump default CPUs for iOS 26/watchOS 26 to A12/S6. #152235
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[AArch64] Bump default CPUs for iOS 26/watchOS 26 to A12/S6. #152235
Conversation
iOS 26/watchOS 26 deprecate some devices, allowing the default CPU to be raised based on the deployment target. watchOS 26 also introduces arm64 (vs. arm64_32/arm64e). The defaults are now: - arm64-apple-ios26 apple-a12 - arm64-apple-watchos26 apple-s6 - arm64_32-apple-watchos26 apple-s6 - arm64e-apple-watchos26 apple-s6 Left unchanged are: - arm64-apple-tvos26 apple-a7 - arm64e-apple-tvos26 apple-a12 - arm64e-apple-ios26 apple-a12 - arm64_32-apple-watchos11 apple-s4 While there, rewrite an outdated comment in a related Mac test.
@llvm/pr-subscribers-backend-aarch64 @llvm/pr-subscribers-clang Author: Ahmed Bougacha (ahmedbougacha) ChangesiOS 26/watchOS 26 deprecate some devices, allowing the default CPU to be raised based on the deployment target. watchOS 26 also introduces arm64 (vs. arm64_32/arm64e). The defaults are now:
Left unchanged are:
While there, rewrite an outdated comment in a related Mac test. Full diff: https://github.com/llvm/llvm-project/pull/152235.diff 3 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index 418f9fd9ca4c4..98f5efbe5652f 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -52,6 +52,22 @@ std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
return "apple-m1";
}
+ if (Triple.getOS() == llvm::Triple::IOS) {
+ assert(!Triple.isSimulatorEnvironment() && "iossim should be mac-like");
+ // iOS 26 only runs on apple-a12 and later CPUs.
+ if (!Triple.isOSVersionLT(26))
+ return "apple-a12";
+ }
+
+ if (Triple.isWatchOS()) {
+ assert(!Triple.isSimulatorEnvironment() && "watchossim should be mac-like");
+ // arm64_32/arm64e watchOS requires S4 before watchOS 26, S6 after.
+ if (Triple.getArch() == llvm::Triple::aarch64_32 || Triple.isArm64e())
+ return Triple.isOSVersionLT(26) ? "apple-s4" : "apple-s6";
+ // arm64 (non-e, non-32) watchOS comes later, and requires S6 anyway.
+ return "apple-s6";
+ }
+
if (Triple.isXROS()) {
// The xrOS simulator runs on M1 as well, it should have been covered above.
assert(!Triple.isSimulatorEnvironment() && "xrossim should be mac-like");
diff --git a/clang/test/Driver/aarch64-cpu-defaults-appleos26.c b/clang/test/Driver/aarch64-cpu-defaults-appleos26.c
new file mode 100644
index 0000000000000..7ad460ee86fcf
--- /dev/null
+++ b/clang/test/Driver/aarch64-cpu-defaults-appleos26.c
@@ -0,0 +1,22 @@
+/// iOS 26 and watchOS 26 bump the default arm64 CPU targets.
+
+/// arm64 iOS 26 defaults to apple-a12. arm64e already did.
+// RUN: %clang -target arm64-apple-ios26 -### -c %s 2>&1 | FileCheck %s --check-prefix=A12
+// RUN: %clang -target arm64e-apple-ios26 -### -c %s 2>&1 | FileCheck %s --check-prefix=A12
+
+// arm64e/arm64_32 watchOS 26 default to apple-s6.
+// RUN: %clang -target arm64e-apple-watchos26 -### -c %s 2>&1 | FileCheck %s --check-prefix=S6
+// RUN: %clang -target arm64_32-apple-watchos26 -### -c %s 2>&1 | FileCheck %s --check-prefix=S6
+
+// arm64 is new in watchOS 26, and defaults to apple-s6.
+// RUN: %clang -target arm64-apple-watchos26 -### -c %s 2>&1 | FileCheck %s --check-prefix=S6
+
+/// llvm usually treats tvOS like iOS, but it runs on different hardware.
+// RUN: %clang -target arm64-apple-tvos26 -### -c %s 2>&1 | FileCheck %s --check-prefix=A7
+// RUN: %clang -target arm64e-apple-tvos26 -### -c %s 2>&1 | FileCheck %s --check-prefix=A12
+
+/// Simulators are tested with other Mac-like targets in aarch64-mac-cpus.c.
+
+// A12: "-target-cpu" "apple-a12"
+// S6: "-target-cpu" "apple-s6"
+// A7: "-target-cpu" "apple-a7"
diff --git a/clang/test/Driver/aarch64-mac-cpus.c b/clang/test/Driver/aarch64-mac-cpus.c
index 8d23ad8c956fd..1aef1ae285e86 100644
--- a/clang/test/Driver/aarch64-mac-cpus.c
+++ b/clang/test/Driver/aarch64-mac-cpus.c
@@ -1,4 +1,4 @@
-// arm64 Mac-based targets default to Apple A13.
+// arm64/arm64e Mac-based targets default to Apple M1.
// RUN: %clang --target=arm64-apple-macos -### -c %s 2>&1 | FileCheck %s
// RUN: %clang --target=arm64-apple-ios-macabi -### -c %s 2>&1 | FileCheck %s
|
@llvm/pr-subscribers-clang-driver Author: Ahmed Bougacha (ahmedbougacha) ChangesiOS 26/watchOS 26 deprecate some devices, allowing the default CPU to be raised based on the deployment target. watchOS 26 also introduces arm64 (vs. arm64_32/arm64e). The defaults are now:
Left unchanged are:
While there, rewrite an outdated comment in a related Mac test. Full diff: https://github.com/llvm/llvm-project/pull/152235.diff 3 Files Affected:
diff --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index 418f9fd9ca4c4..98f5efbe5652f 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -52,6 +52,22 @@ std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
return "apple-m1";
}
+ if (Triple.getOS() == llvm::Triple::IOS) {
+ assert(!Triple.isSimulatorEnvironment() && "iossim should be mac-like");
+ // iOS 26 only runs on apple-a12 and later CPUs.
+ if (!Triple.isOSVersionLT(26))
+ return "apple-a12";
+ }
+
+ if (Triple.isWatchOS()) {
+ assert(!Triple.isSimulatorEnvironment() && "watchossim should be mac-like");
+ // arm64_32/arm64e watchOS requires S4 before watchOS 26, S6 after.
+ if (Triple.getArch() == llvm::Triple::aarch64_32 || Triple.isArm64e())
+ return Triple.isOSVersionLT(26) ? "apple-s4" : "apple-s6";
+ // arm64 (non-e, non-32) watchOS comes later, and requires S6 anyway.
+ return "apple-s6";
+ }
+
if (Triple.isXROS()) {
// The xrOS simulator runs on M1 as well, it should have been covered above.
assert(!Triple.isSimulatorEnvironment() && "xrossim should be mac-like");
diff --git a/clang/test/Driver/aarch64-cpu-defaults-appleos26.c b/clang/test/Driver/aarch64-cpu-defaults-appleos26.c
new file mode 100644
index 0000000000000..7ad460ee86fcf
--- /dev/null
+++ b/clang/test/Driver/aarch64-cpu-defaults-appleos26.c
@@ -0,0 +1,22 @@
+/// iOS 26 and watchOS 26 bump the default arm64 CPU targets.
+
+/// arm64 iOS 26 defaults to apple-a12. arm64e already did.
+// RUN: %clang -target arm64-apple-ios26 -### -c %s 2>&1 | FileCheck %s --check-prefix=A12
+// RUN: %clang -target arm64e-apple-ios26 -### -c %s 2>&1 | FileCheck %s --check-prefix=A12
+
+// arm64e/arm64_32 watchOS 26 default to apple-s6.
+// RUN: %clang -target arm64e-apple-watchos26 -### -c %s 2>&1 | FileCheck %s --check-prefix=S6
+// RUN: %clang -target arm64_32-apple-watchos26 -### -c %s 2>&1 | FileCheck %s --check-prefix=S6
+
+// arm64 is new in watchOS 26, and defaults to apple-s6.
+// RUN: %clang -target arm64-apple-watchos26 -### -c %s 2>&1 | FileCheck %s --check-prefix=S6
+
+/// llvm usually treats tvOS like iOS, but it runs on different hardware.
+// RUN: %clang -target arm64-apple-tvos26 -### -c %s 2>&1 | FileCheck %s --check-prefix=A7
+// RUN: %clang -target arm64e-apple-tvos26 -### -c %s 2>&1 | FileCheck %s --check-prefix=A12
+
+/// Simulators are tested with other Mac-like targets in aarch64-mac-cpus.c.
+
+// A12: "-target-cpu" "apple-a12"
+// S6: "-target-cpu" "apple-s6"
+// A7: "-target-cpu" "apple-a7"
diff --git a/clang/test/Driver/aarch64-mac-cpus.c b/clang/test/Driver/aarch64-mac-cpus.c
index 8d23ad8c956fd..1aef1ae285e86 100644
--- a/clang/test/Driver/aarch64-mac-cpus.c
+++ b/clang/test/Driver/aarch64-mac-cpus.c
@@ -1,4 +1,4 @@
-// arm64 Mac-based targets default to Apple A13.
+// arm64/arm64e Mac-based targets default to Apple M1.
// RUN: %clang --target=arm64-apple-macos -### -c %s 2>&1 | FileCheck %s
// RUN: %clang --target=arm64-apple-ios-macabi -### -c %s 2>&1 | FileCheck %s
|
// iOS 26 only runs on apple-a12 and later CPUs. | ||
if (!Triple.isOSVersionLT(26)) | ||
return "apple-a12"; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about the two other places in the LTO backend where we do this sort of platform default thing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right, I think of those as a remnant of early LTO support, a default fallback for cases where the frontend doesn't set up the target IR attributes.
The last addition was arm64e/a12, when we still had unattributed functions, in obscure corners of clang IRGen that synthesize thunks and wrappers. I'd expect those to be thoroughly eliminated now, after the waves of ptrauth attribute variations that will break if missing, and can't rely on this sort of late fallback.
So I'd say we could probably try to remove the LTO logic altogether, at the risk of breaking some library users without a clang-equivalent driver.
There's a case to be made this logic should be an llvm default backing a driver override, which would help other users. I don't think that's a bad idea, and it seems it'd belong in TargetParser? But overall I think it's just another on the long list of low-level choices that clang has to do and are hard to separate; using clang seems unavoidable (also see Jordan and John's old llvm devmtg talk "Skip the FFI" ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related: at some point we discussed having a way of describing default function attributes in a module (e.g., using module flags), for cases where functions are generated later that IRGen, in the IR pipeline. Of course I can't find any links anymore, but I'd expect those to have another (frontend-IRGen'd) function to use as a template. Of course one can imagine some hypothetical transform where that isn't true ;)
if (Triple.getArch() == llvm::Triple::aarch64_32 || Triple.isArm64e()) | ||
return Triple.isOSVersionLT(26) ? "apple-s4" : "apple-s6"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (Triple.getArch() == llvm::Triple::aarch64_32 || Triple.isArm64e()) | |
return Triple.isOSVersionLT(26) ? "apple-s4" : "apple-s6"; | |
if ((Triple.getArch() == llvm::Triple::aarch64_32 || Triple.isArm64e()) && | |
Triple.isOSVersionLT(26)) | |
return "apple-s4"; |
Maybe? Seems nicer to avoid nested conditionals, but not a strong opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, that could be a sensible alternative, but I tried to keep it structured in a way that keeps each policy clearly delineated: in this case there are distinct reasons we end up with S6; the same applies later for the various ways we end up with A12.
iOS 26/watchOS 26 deprecate some devices, allowing the default CPU to be raised based on the deployment target.
watchOS 26 also introduces arm64 (vs. arm64_32/arm64e).
The defaults are now:
Left unchanged are:
While there, rewrite an outdated comment in a related Mac test.