Skip to content

Arm64 R2R: fold adrp+add+ldr into adrp+ldr[#:lo12:]#129589

Merged
EgorBo merged 7 commits into
dotnet:mainfrom
EgorBo:arm64-r2r-fold-pageoffset-ldr
Jun 26, 2026
Merged

Arm64 R2R: fold adrp+add+ldr into adrp+ldr[#:lo12:]#129589
EgorBo merged 7 commits into
dotnet:mainfrom
EgorBo:arm64-r2r-fold-pageoffset-ldr

Conversation

@EgorBo

@EgorBo EgorBo commented Jun 18, 2026

Copy link
Copy Markdown
Member

On Arm64 R2R (and runtime JIT), a value load through a relocatable indirection cell emits adrp + add + ldr. The page offset can be folded directly into the ldr via a new PAGEOFFSET_12L relocation, saving one instruction per access. This is what x64 gets for free with RIP-relative addressing, and the managed AOT object-writer side already supported 12L — only RyuJIT never emitted it.

For example:

public static void Test()
{
    Console.WriteLine("hello");
}

Before → after (Arm64 R2R):

 adrp x0, [HIGH RELOC]              adrp x0, [HIGH RELOC]
 add  x0, x0, [LOW RELOC]     →     ldr  x0, [x0, [LOW RELOC]]   ← folded
 ldr  x0, [x0]                      ldr  x0, [x0]
 ldr  x0, [x0]

-2.1 MB on libraries.crossgen SPMI collection.

System.Private.CoreLib.dll (R2R): 18032 KB -> 17840 KB (-192 KB)

Add an Arm64 PAGEOFFSET_12L relocation so a value load through a
relocatable cell folds the page offset into the ldr, saving one
instruction per access (R2R and runtime JIT).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 18, 2026 18:45
@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jun 18, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new Arm64 relocation kind (ARM64_PAGEOFFSET_12L) and teaches RyuJIT (and supporting infrastructure) to fold a relocatable adrp + add + ldr sequence into adrp + ldr [#:lo12:], saving an instruction for common indirection-cell value loads in R2R/relocatable codegen.

Changes:

  • Add CorInfoReloc::ARM64_PAGEOFFSET_12L and wire it through the JIT/EE boundary (including a JIT/EE GUID bump).
  • Introduce GetArm64Rel12Ldr / PutArm64Rel12Ldr helpers and use them in VM and SuperPMI relocation fixups.
  • Implement an emitter peephole to remove the relocatable add and emit an ldr carrying the new relocation.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/coreclr/vm/jitinterface.cpp Handles the new ARM64_PAGEOFFSET_12L relocation in the runtime relocation fixer.
src/coreclr/utilcode/util.cpp Adds LDR-specific rel12 extract/deposit helpers for Arm64.
src/coreclr/tools/superpmi/superpmi-shared/spmiutil.h Declares PutArm64Rel12Ldr for SuperPMI’s relocation patching utilities.
src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp Implements PutArm64Rel12Ldr in SuperPMI’s local copy of utilcode helpers.
src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp Adds stringification and application support for ARM64_PAGEOFFSET_12L during replay normalization.
src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs Extends the managed mirror of CorInfoReloc with ARM64_PAGEOFFSET_12L.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Maps ARM64_PAGEOFFSET_12L to the object-writer relocation type.
src/coreclr/jit/emitarm64.h Declares TryFoldPageOffsetIntoLdr helper for the emitter peephole.
src/coreclr/jit/emitarm64.cpp Implements folding logic and records the new relocation for the folded ldr.
src/coreclr/inc/utilcode.h Declares GetArm64Rel12Ldr / PutArm64Rel12Ldr helpers.
src/coreclr/inc/jiteeversionguid.h Bumps the JIT/EE interface GUID due to the new relocation enum value.
src/coreclr/inc/corinfo.h Adds ARM64_PAGEOFFSET_12L to the native CorInfoReloc enum.

Comment thread src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp
Comment thread src/coreclr/jit/emitarm64.cpp Outdated
EgorBo and others added 2 commits June 18, 2026 21:05
Address review feedback: the predicate gates on EA_SIZE == EA_8BYTE in a
general register, which includes GCREF/BYREF; "integer loads" was misleading.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 18, 2026 19:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Comment thread src/coreclr/jit/emitarm64.cpp
@EgorBo
EgorBo marked this pull request as ready for review June 19, 2026 14:08
@EgorBo
EgorBo requested a review from MichalStrehovsky as a code owner June 19, 2026 14:08
Copilot AI review requested due to automatic review settings June 19, 2026 14:08
@EgorBo

EgorBo commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

/azp list

@azure-pipelines

This comment was marked as resolved.

@EgorBo

EgorBo commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

/azp run runtime-coreclr outerloop, runtime-coreclr crossgen2, runtime-coreclr r2r

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines successfully started running 3 pipeline(s).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 1 comment.

Comment thread src/coreclr/jit/emitarm64.cpp
@EgorBo

EgorBo commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

PTAL @dotnet/jit-contrib all outerloop pipelines passed

Copilot AI review requested due to automatic review settings June 22, 2026 19:43
@EgorBo

EgorBo commented Jun 22, 2026

Copy link
Copy Markdown
Member Author

PTAL @dhartglassMSFT @dotnet/jit-contrib
for VM side @jkotas @MichalStrehovsky?

@EgorBo
EgorBo requested a review from dhartglassMSFT June 22, 2026 19:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

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

Comment thread src/coreclr/inc/corinfo.h
Comment thread src/coreclr/jit/emitarm64.cpp
Comment thread src/coreclr/jit/emitarm64.cpp

@tannergooding tannergooding left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM. Just a couple questions about handling other scenarios (possibly just in the future).

@EgorBo

EgorBo commented Jun 26, 2026

Copy link
Copy Markdown
Member Author

/ba-g timeouts

@EgorBo
EgorBo merged commit de11262 into dotnet:main Jun 26, 2026
125 of 127 checks passed
@EgorBo
EgorBo deleted the arm64-r2r-fold-pageoffset-ldr branch June 26, 2026 10:51
@jkotas jkotas added the tenet-performance Performance related issue label Jun 26, 2026
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 11.0-preview7 milestone Jun 28, 2026
This was referenced Jul 2, 2026
MichalStrehovsky pushed a commit that referenced this pull request Jul 8, 2026
…9966)

Fixes #129936.

PR #129589 added an Arm64 fold of `adrp+add+ldr` into
`adrp+ldr[#:lo12:]` via a 64-bit `PAGEOFFSET_12L` reloc
(`R_AARCH64_LDST64_ABS_LO12_NC`). That reloc encodes the offset scaled
by 8, so the target must be 8-byte aligned. In R2R the relocatable loads
always go through pointer-aligned indirection cells, but NativeAOT can
fold a direct 64-bit load of byte-packed frozen data (4-byte aligned),
which `ld.lld` rejects:

```
ld.lld : error : improper alignment for relocation R_AARCH64_LDST64_ABS_LO12_NC: 0x74A52C is not aligned to 8 bytes
```

The fold is purely a size optimization, so this restricts it to
non-NativeAOT and falls back to the always-safe `adrp+add+ldr`.

Validation (SPMI, linux-arm64):
- `benchmarks.run` (R2R, ~427K contexts): **0 asm diffs** — the win is
preserved.
- `smoke_tests.nativeaot` (18891 ctx): clean replay, no diffs.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jakob Botsch Nielsen <Jakob.botsch.nielsen@gmail.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
On Arm64 R2R (and runtime JIT), a value load through a relocatable
indirection cell emits `adrp + add + ldr`. The page offset can be folded
directly into the `ldr` via a new `PAGEOFFSET_12L` relocation, saving
one instruction per access. This is what x64 gets for free with
RIP-relative addressing, and the managed AOT object-writer side already
supported `12L` — only RyuJIT never emitted it.

For example:

```cs
public static void Test()
{
    Console.WriteLine("hello");
}
```

Before → after (Arm64 R2R):

```asm
 adrp x0, [HIGH RELOC]              adrp x0, [HIGH RELOC]
 add  x0, x0, [LOW RELOC]     →     ldr  x0, [x0, [LOW RELOC]]   ← folded
 ldr  x0, [x0]                      ldr  x0, [x0]
 ldr  x0, [x0]
```

**-2.1 MB** on libraries.crossgen SPMI collection.

System.Private.CoreLib.dll (R2R): 18032 KB -> 17840 KB (**-192 KB**)

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
eiriktsarpalis pushed a commit that referenced this pull request Jul 15, 2026
…9966)

Fixes #129936.

PR #129589 added an Arm64 fold of `adrp+add+ldr` into
`adrp+ldr[#:lo12:]` via a 64-bit `PAGEOFFSET_12L` reloc
(`R_AARCH64_LDST64_ABS_LO12_NC`). That reloc encodes the offset scaled
by 8, so the target must be 8-byte aligned. In R2R the relocatable loads
always go through pointer-aligned indirection cells, but NativeAOT can
fold a direct 64-bit load of byte-packed frozen data (4-byte aligned),
which `ld.lld` rejects:

```
ld.lld : error : improper alignment for relocation R_AARCH64_LDST64_ABS_LO12_NC: 0x74A52C is not aligned to 8 bytes
```

The fold is purely a size optimization, so this restricts it to
non-NativeAOT and falls back to the always-safe `adrp+add+ldr`.

Validation (SPMI, linux-arm64):
- `benchmarks.run` (R2R, ~427K contexts): **0 asm diffs** — the win is
preserved.
- `smoke_tests.nativeaot` (18891 ctx): clean replay, no diffs.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jakob Botsch Nielsen <Jakob.botsch.nielsen@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI tenet-performance Performance related issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants