Skip to content

Stop RyuJIT from injecting thumb bit under ILC, remove ObjectWriter compensation#126294

Open
MichalStrehovsky wants to merge 3 commits intodotnet:mainfrom
MichalStrehovsky:remove-thumb-bit-compensation
Open

Stop RyuJIT from injecting thumb bit under ILC, remove ObjectWriter compensation#126294
MichalStrehovsky wants to merge 3 commits intodotnet:mainfrom
MichalStrehovsky:remove-thumb-bit-compensation

Conversation

@MichalStrehovsky
Copy link
Copy Markdown
Member

Should match what was done in #125421.

ILC defines ARM32 method symbols with the thumb bit (+1) set per AAELF convention. RyuJIT was also adding +1 to movw/movt label addresses, causing double-counting that ObjectWriter had to compensate for with maskThumbBitOut/maskThumbBitIn logic.

Guard the thumb bit injection in emitarm.cpp so it only applies for ReadyToRun and runtime JIT (where symbols don't carry the thumb bit), not for ILC.

Replace the maskThumbBit compensation in ObjectWriter with a simpler approach: for BRANCH24 only, strip the thumb bit from the symbol value since the encoding can't represent it. For MOV32, the symbol value (with thumb bit) flows through directly.

Cc @jakobbotsch @jkoritzinsky

…ompensation

ILC defines ARM32 method symbols with the thumb bit (+1) set per
AAELF convention. RyuJIT was also adding +1 to movw/movt label
addresses, causing double-counting that ObjectWriter had to
compensate for with maskThumbBitOut/maskThumbBitIn logic.

Guard the thumb bit injection in emitarm.cpp so it only applies
for ReadyToRun and runtime JIT (where symbols don't carry the
thumb bit), not for ILC.

Replace the maskThumbBit compensation in ObjectWriter with a
simpler approach: for BRANCH24 only, strip the thumb bit from
the symbol value since the encoding can't represent it. For
MOV32, the symbol value (with thumb bit) flows through directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 30, 2026 07:05
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib
See info in area-owners.md if you want to be subscribed.

@MichalStrehovsky
Copy link
Copy Markdown
Member Author

/azp run runtime-coreclr outerloop, runtime-nativeaot-outerloop

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

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

This PR aligns ARM32 Thumb-bit handling between ILC and RyuJIT by preventing double-injection of the Thumb bit (+1) into relocation computations, and by simplifying ObjectWriter’s Thumb-bit adjustment logic to match AAELF expectations.

Changes:

  • Update ARM32 JIT emission to only inject the Thumb bit for ReadyToRun and runtime JIT scenarios (not ILC).
  • Simplify ObjectWriter relocation resolution: strip the Thumb bit only for THUMB_BRANCH24 (since the encoding can’t represent it), while letting THUMB_MOV32_PCREL flow through unchanged.

Reviewed changes

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

File Description
src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs Removes prior mask-in/mask-out compensation and replaces it with BRANCH24-only Thumb-bit stripping during same-section relocation resolution.
src/coreclr/jit/emitarm.cpp Guards movw/movt label Thumb-bit injection so ILC doesn’t double-count Thumb-bit-in-symbol + Thumb-bit-in-addend.

Copy link
Copy Markdown
Member

@jkoritzinsky jkoritzinsky left a comment

Choose a reason for hiding this comment

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

I'd personally like to go the other direction (encode the CodeDelta into the reloc when needed in the ObjectDataBuilder emission in each node) so we can be consistent with R2R or come up with a solution for emitting it for R2R in the ObjectWriter.

@MichalStrehovsky
Copy link
Copy Markdown
Member Author

I'd personally like to go the other direction (encode the CodeDelta into the reloc when needed in the ObjectDataBuilder emission in each node) so we can be consistent with R2R or come up with a solution for emitting it for R2R in the ObjectWriter.

AAELF requires that the symbols are defined with the THUMB bit set. ReadyToRun will have to do this too if we ever start emitting ELF binaries as R2R. So if we want to unify, we'd unify on the THUMB bit being set in the symbol definition already the way native AOT does it (i.e. not a +1 CodeDelta).

This PR just makes things consistent with how we did this in #125421 so that we don't have two different ways. With some luck, we'll drop ARM32 support before we need ELF ReadyToRun.

MichalStrehovsky and others added 2 commits March 31, 2026 09:49
Clarified comments regarding method symbols and thumb bit handling in relocation.
Co-authored-by: Jan Kotas <jkotas@microsoft.com>
Copilot AI review requested due to automatic review settings March 31, 2026 00:49
@MichalStrehovsky
Copy link
Copy Markdown
Member Author

/azp run runtime-coreclr outerloop, runtime-nativeaot-outerloop

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 2 pipeline(s).

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

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

@jkoritzinsky
Copy link
Copy Markdown
Member

In that case, can we open up a follow up issue to remove the CodeDelta concept from R2R (and figure out which relocs are the ones that break there if it's added)? I want to eventually unify ObjectWriter between R2R and NAOT so that's a prerequisite at this point.

@MichalStrehovsky
Copy link
Copy Markdown
Member Author

In that case, can we open up a follow up issue to remove the CodeDelta concept from R2R (and figure out which relocs are the ones that break there if it's added)? I want to eventually unify ObjectWriter between R2R and NAOT so that's a prerequisite at this point.

We track this in #125788.

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.

5 participants