Skip to content

[release/11.0.1xx-preview4] [dotnet] Fix R2R --instruction-set computation for iOS/tvOS device builds#25365

Closed
rolfbjarne wants to merge 2 commits intorelease/11.0.1xx-preview4from
dev/rolf/backport-pr-25337-release/11.0.1xx-preview4-2026-05-07
Closed

[release/11.0.1xx-preview4] [dotnet] Fix R2R --instruction-set computation for iOS/tvOS device builds#25365
rolfbjarne wants to merge 2 commits intorelease/11.0.1xx-preview4from
dev/rolf/backport-pr-25337-release/11.0.1xx-preview4-2026-05-07

Conversation

@rolfbjarne
Copy link
Copy Markdown
Member

Summary

_ComputeInstructionSetForCrossgen2 was passing $(TargetFramework) (the short form like net11.0-ios) as TargetFrameworkMoniker. The base task calls TargetFramework.Parse, which only handles the long comma-delimited form (.NETCoreApp,Version=v11.0,Profile=ios); the short form silently parses to an empty TargetFramework whose Platform getter falls through to ApplePlatform.MacOSX.

For an ios-arm64 build the platform was therefore reported as macOS, so ComputeMinimumInstructionSet routed to ComputeMacInstructionSet, which returns apple-m1 for any arm64 RID. crossgen2 was then invoked with --instruction-set:apple-m1 even on iOS device builds.

Impact

apple-m1 requires ARMv8.5 features. Pre-A14 iOS devices (iPhone XR/A12, iPhone 11/A13, etc.) do not implement them, so the runtime rejects the R2R image at load time and falls back to the interpreter — defeating R2R on a wide range of supported devices and visibly regressing cold-start.

This was originally observed in MAUI/M365 startup measurements where CoreCLR Release on iPhone XR was ~2× slower than Mono Release; profiling pointed at interpreter fallback, and the binlog showed --instruction-set:apple-m1 on the crossgen2 line plus the misleading Computed instruction set 'apple-m1' for macOS 15.0 log message for an iOS build.

Fix

The other call sites in the same file already use $(_ComputedTargetFrameworkMoniker) (the long form expanded by the shared targets). Align this one with them — one-line change.


Co-authored-by: Milos Kotlar kotlarmilos@users.noreply.github.com
Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com
Co-authored-by: Rolf Bjarne Kvinge rokvin@microsoft.com

Backport of #25337.

kotlarmilos and others added 2 commits May 7, 2026 21:08
…ilds

`_ComputeInstructionSetForCrossgen2` was passing `$(TargetFramework)` (the
short form like `net11.0-ios`) as `TargetFrameworkMoniker`. The base task
calls `TargetFramework.Parse` which only handles the long
comma-delimited form (`.NETCoreApp,Version=v11.0,Profile=ios`); the short
form silently parses to an empty `TargetFramework` whose `Platform` getter
falls through to `ApplePlatform.MacOSX`.

For an `ios-arm64` build the platform was therefore reported as macOS,
so `ComputeMinimumInstructionSet` routed to `ComputeMacInstructionSet`,
which returns `apple-m1` for any arm64 RID. crossgen2 was then invoked
with `--instruction-set:apple-m1` even on iOS device builds.

`apple-m1` requires ARMv8.5 features. Pre-A14 iOS devices (iPhone XR/A12,
iPhone 11/A13) do not implement them, so the runtime rejects the R2R
image at load time and falls back to the interpreter, defeating R2R on
a wide range of supported devices.

The other call sites in the file already use $(_ComputedTargetFrameworkMoniker)
(the long form). Align this one with them.

After the fix, `ios-arm64` device builds pick the oldest-supported-device
ISA via the device table walk (e.g. `armv8-a` for SupportedOSPlatformVersion
15.0–17.x, `armv8.3-a` for iOS 18.0+).

Verified locally on a fresh `dotnet new maui` project (`net11.0-ios`,
ios pack 26.4.11531-net11-p5):

  - Before: `Computed instruction set 'apple-m1' for macOS 15.0` and
    `--instruction-set:apple-m1` on the crossgen2 cmdline.
  - After:  `Computed instruction set 'armv8-a' for iOS 15.0` and
    `--instruction-set:armv8-a` on the crossgen2 cmdline.

iPhone 13 (A15, ARMv8.5) cold-start unchanged within noise (~228 ms);
older devices should now actually use R2R instead of the interpreter.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 7, 2026 19:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes ReadyToRun (crossgen2) instruction-set selection for iOS/tvOS device builds by ensuring _ComputeInstructionSetForCrossgen2 passes a long TargetFrameworkMoniker (with the correct Apple platform profile) to the ComputeInstructionSet task, preventing iOS/tvOS arm64 builds from being misdetected as macOS and incorrectly using apple-m1.

Changes:

  • Update _ComputeInstructionSetForCrossgen2 to pass $(_ComputedTargetFrameworkMoniker) instead of $(TargetFramework) to ComputeInstructionSet.
  • Refresh AppSizeTest expected size baselines across iOS/tvOS/macOS/MacCatalyst configurations to match new build outputs.

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated no comments.

Show a summary per file
File Description
dotnet/targets/Microsoft.Sdk.R2R.targets Fix ComputeInstructionSet input to use the long computed TFM so iOS/tvOS device builds compute the correct instruction set.
tests/dotnet/UnitTests/expected/TVOS-NativeAOT-size.txt Update expected tvOS NativeAOT bundle size baseline.
tests/dotnet/UnitTests/expected/TVOS-MonoVM-size.txt Update expected tvOS MonoVM bundle size baseline.
tests/dotnet/UnitTests/expected/TVOS-MonoVM-interpreter-size.txt Update expected tvOS MonoVM (interpreter) bundle size baseline.
tests/dotnet/UnitTests/expected/TVOS-CoreCLR-R2R-size.txt Update expected tvOS CoreCLR R2R bundle size baseline.
tests/dotnet/UnitTests/expected/TVOS-CoreCLR-Interpreter-size.txt Update expected tvOS CoreCLR interpreter bundle size baseline.
tests/dotnet/UnitTests/expected/MacOSX-NativeAOT-size.txt Update expected macOS NativeAOT bundle size baseline.
tests/dotnet/UnitTests/expected/MacOSX-CoreCLR-R2R-size.txt Update expected macOS CoreCLR R2R bundle size baseline.
tests/dotnet/UnitTests/expected/MacOSX-CoreCLR-Interpreter-size.txt Update expected macOS CoreCLR interpreter bundle size baseline.
tests/dotnet/UnitTests/expected/MacCatalyst-NativeAOT-size.txt Update expected Mac Catalyst NativeAOT bundle size baseline.
tests/dotnet/UnitTests/expected/MacCatalyst-MonoVM-size.txt Update expected Mac Catalyst MonoVM bundle size baseline.
tests/dotnet/UnitTests/expected/MacCatalyst-MonoVM-interpreter-size.txt Update expected Mac Catalyst MonoVM (interpreter) bundle size baseline.
tests/dotnet/UnitTests/expected/MacCatalyst-CoreCLR-R2R-size.txt Update expected Mac Catalyst CoreCLR R2R bundle size baseline.
tests/dotnet/UnitTests/expected/MacCatalyst-CoreCLR-Interpreter-size.txt Update expected Mac Catalyst CoreCLR interpreter bundle size baseline.
tests/dotnet/UnitTests/expected/iOS-NativeAOT-size.txt Update expected iOS NativeAOT bundle size baseline.
tests/dotnet/UnitTests/expected/iOS-MonoVM-size.txt Update expected iOS MonoVM bundle size baseline.
tests/dotnet/UnitTests/expected/iOS-MonoVM-interpreter-size.txt Update expected iOS MonoVM (interpreter) bundle size baseline.
tests/dotnet/UnitTests/expected/iOS-CoreCLR-R2R-size.txt Update expected iOS CoreCLR R2R bundle size baseline.
tests/dotnet/UnitTests/expected/iOS-CoreCLR-Interpreter-size.txt Update expected iOS CoreCLR interpreter bundle size baseline.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@kotlarmilos kotlarmilos self-requested a review May 8, 2026 09:04
@rolfbjarne
Copy link
Copy Markdown
Member Author

Closing, too late to get into P4 at this point.

@rolfbjarne rolfbjarne closed this May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants