dotnet / dotnet/android

[CoreCLR] Support selective optimistic ARM64 ISA configuration for ReadyToRun

Open
#12,742 0 comments 0 reactions 0 assignees View on GitHub
needs-triage
Dominant language
C#
Stars
2.1k
Forks
579
Avg merge
1d 21h
Merged PRs (30d)
257

Description

### Android framework version

net11.0-android (Preview)

### Affected platform version

.NET 11 / CoreCLR ReadyToRun, following up on https://github.com/dotnet/android/pull/12722. The detailed experiment used Crossgen2 11.0.0-rc.1.26431.118.

### Description

PR #12722 excludes RCPC2 from .NET for Android ARM64 ReadyToRun code by disabling automatic optimistic additions and explicitly enabling the remaining candidate features:

```text
--instruction-set:-optimistic,aes,crc,dotprod,lse,rcpc,rdma,sha1,sha2
```

This solves the immediate RCPC2 compatibility problem, but the existing Crossgen2 command-line semantics cannot express the policy we actually want: **remove RCPC2 from the optimistic set while leaving other features opportunistic and method-guarded**.

As Vlad suggested in the PR review, Crossgen2 should provide an option to modify the optimistic ISA set independently from the supported baseline and explicitly unsupported set.

The current alternatives all have undesirable semantics:

- `--instruction-set:-optimistic` disables every automatic optimistic ARM64 feature.
- `--instruction-set:-optimistic,...` makes each explicitly added feature an eager, image-wide baseline requirement.
- `--instruction-set:-rcpc2` records RCPC2 as explicitly unsupported. On an RCPC2-capable device, the eager negative guard can disable the entire composite R2R image.

The proposed Crossgen2 capability could take a form such as an optimistic-only add/remove option, but the exact CLI/API should be designed in dotnet/runtime. Required semantics:

- Removing RCPC2 prevents RCPC2 lowering and positive RCPC2 method guards.
- It does not assert that RCPC2 must be absent.
- It does not promote unrelated optimistic features into eager image requirements.
- It preserves runtime JIT/tiered-compilation use of the actual device capabilities.

#### Evidence from the MAUI sample-content app

The exact ARM64 composite contained 19,792 native bodies.

| ISA | Instructions with the PR policy | Bodies | Bodies requested before Ready |
|---|---:|---:|---:|
| LSE | 191 | 138 | 78-80 |
| RCPC | 1,213 | 491 | 203 |
| AES | 0 | 0 | 0 |
| CRC | 0 | 0 | 0 |
| DotProd | 0 | 0 | 0 |
| RDM (`rdma`) | 0 | 0 | 0 |
| SHA1 | 0 | 0 | 0 |
| SHA2 | 0 | 0 | 0 |
| RCPC2 | 0 | 0 | 0 |

RCPC2 is zero because `-optimistic` disabled automatic additions and RCPC2 was not re-enabled. The stock optimistic image emitted 1,084 RCPC2 instructions across 447 bodies.

RCPC is widely emitted, but in this workload its observed code-generation difference is `LDAR`/`LDARB`/`LDARH` becoming `LDAPR`/`LDAPRB`/`LDAPRH`. It does not reduce code size, method count, or acquire-load instruction count. We have not demonstrated an independent startup benefit from requiring RCPC.

LSE is genuinely used for atomics and is already part of the pinned Android ARM64 ReadyToRun baseline. The emitted instructions include `CASAL`, `LDADDAL`, `SWPAL`, and `LDSETAL` in locking, task, cancellation, and thread-pool code.

#### Android baseline decision

We should separately decide whether the Android ARM64 ReadyToRun baseline should remain `armv8-a + lse` or become `armv8-a + lse + rcpc`.

Our device/SoC research suggests:

- LSE/RCPC adoption is approximately 85-94% among recent 2025-2026 ARM64 phone sales.
- Across the full 2016-present installed/sold history, LSE/RCPC coverage is closer to roughly half because Cortex-A53/A72/A73-era devices lack them.
- RCPC2 remains absent from many phones sold today, including high-volume Cortex-A78/A55-class Qualcomm, MediaTek, Exynos, and Unisoc devices. It should not be part of a broad Android R2R baseline.

Questions to resolve:

1. What Android device-age/support window should define the ReadyToRun presumed-majority baseline?
2. Is the potential `LDAPR` benefit sufficient to justify making RCPC an image-wide requirement?
3. Should LSE remain in the baseline given the long tail of older ARM64 devices without it?
4. Should Android instead use the conservative baseline and selectively optimistic method guards wherever possible?

#### Proposed completion criteria

- Add a Crossgen2 mechanism to add/remove optimistic ISAs independently of supported and explicitly unsupported ISAs.
- Add runtime tests proving that removing RCPC2 from optimism produces neither a positive RCPC2 guard nor a negative RCPC2 eager requirement.
- Confirm that RCPC-capable and RCPC2-capable devices can still use the resulting image.
- Document the distinction between baseline, optimistic, and explicitly unsupported ISA sets.
- Update .NET for Android to use the new mechanism after deciding the intended ARM64 baseline.

### Steps to Reproduce

1. Build the .NET MAUI `dotnet new maui --sample-content` app for `android-arm64`, Release, CoreCLR, trimming, partial composite ReadyToRun.
2. Build the stock optimistic image and inspect its Crossgen2 map/disassembly. It contains RCPC and RCPC2 guarded methods.
3. Build with `--instruction-set:-rcpc2` and run it on an RCPC2-capable device. The eager negative requirement can disable the composite image.
4. Build with `--instruction-set:-optimistic`. RCPC and RCPC2 are both removed, along with the other optimistic features.
5. Build with `--instruction-set:-optimistic,aes,crc,dotprod,lse,rcpc,rdma,sha1,sha2`. RCPC2 is absent, but every listed feature becomes an eager image-level requirement.
6. Observe that none of the existing forms expresses “retain the normal optimistic set except RCPC2.”

### Did you find any workaround?

`--instruction-set:-optimistic` is the safest current workaround, but it disables all optimistic ARM64 features. The explicit list used by PR #12722 preserves RCPC lowering, but raises seven optional features to image-wide baseline requirements and therefore has a larger compatibility risk.

### Relevant log output

```shell
# Current PR policy
--instruction-set:-optimistic,aes,crc,dotprod,lse,rcpc,rdma,sha1,sha2

# Exact emitted code in the sample
LSE: 191 instructions / 138 bodies / 78-80 startup-requested bodies
RCPC: 1213 instructions / 491 bodies / 203 startup-requested bodies
AES, CRC, DotProd, RDM, SHA1, SHA2, RCPC2: 0 instructions

# Stock optimistic image
RCPC: 279 instructions / 156 bodies
RCPC2: 1084 instructions / 447 bodies

# Current eager requirement
ArmBase + AdvSimd + Aes + Crc32 + Dp + Rdm + Sha1 + Sha256 + Atomics + Rcpc
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by reviewing PR #12722 and reproducing the listed Crossgen2 instruction-set commands with the .NET MAUI sample-content app. Design and validate a mechanism that changes only the optimistic ISA set, then add the proposed runtime tests and document the three ISA-set distinctions. After the Android baseline decision, update .NET for Android to use it.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, csharp
Domain
build-system, mobile, performance
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.