Skip to content

[clr-ios] Fix Vector<T> width and R2R AVX baseline mismatch on x64 iOS/tvOS simulators#129012

Merged
kotlarmilos merged 10 commits into
dotnet:mainfrom
kotlarmilos:fix-interp-vectort-128-mobile-x64
Jun 8, 2026
Merged

[clr-ios] Fix Vector<T> width and R2R AVX baseline mismatch on x64 iOS/tvOS simulators#129012
kotlarmilos merged 10 commits into
dotnet:mainfrom
kotlarmilos:fix-interp-vectort-128-mobile-x64

Conversation

@kotlarmilos

@kotlarmilos kotlarmilos commented Jun 4, 2026

Copy link
Copy Markdown
Member

Description

The interpreter only supports 128-bit Vector, but on Mac Catalyst and iOS simulator x64 it was ending up with 256-bit Vector, which is what caused the NullReferenceException in Vector.get_IsHardwareAccelerated. The runtime already limits Vector to 128-bit for the full interpreter mode, but it wasn't doing so on no-JIT builds where everything is interpreted anyway, so AVX2 on x64 silently bumped it up to 256-bit. This change applies the same 128-bit limit whenever the interpreter is the only thing running code. arm64 was never affected since Vector is always 128-bit there.

Crossgen2 had the matching problem where it presumed an x86-64-v3 (AVX2) ReadyToRun baseline for the Apple x64 simulator targets, so the precompiled R2R code and the interpreter disagreed on the Vector width. It now uses the x86-64-v2 baseline for the iOS/tvOS simulators as well, matching osx and maccatalyst, so both share the same 128-bit view. The x64 simulators also run under Rosetta, which does not support AVX, so presuming it was incorrect regardless.

As defense in depth, when an eager fixup failure disables R2R on a no-JIT runtime where the image was compiled with stripped IL bodies (so there is no IL to fall back to), the runtime now fails fast with a clear message instead of running the throw stub left in place of the IL, which previously surfaced as an opaque stack overflow.

Fixes #128901
Fixes #128898

…-JIT x64

The interpreter only supports 128-bit Vector<T>, but on Mac Catalyst and
iOS simulator x64 it was ending up with 256-bit Vector<T>, which caused the
NullReferenceException in Vector.get_IsHardwareAccelerated. The runtime
already limits Vector<T> to 128-bit for the full interpreter mode, but it
wasn't doing so on no-JIT builds where everything is interpreted anyway, so
AVX2 on x64 silently bumped it up to 256-bit. Apply the same 128-bit limit
whenever the interpreter is the only thing running code. arm64 was never
affected since Vector<T> is always 128-bit there.

Related dotnet#128898

Fixes dotnet#128901

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 4, 2026 19:59
@kotlarmilos kotlarmilos changed the title [clr-ios] Fix interpreter NullReferenceException with Vector<T> on no-JIT x64 (Mac Catalyst / iOS simulator) [clr-ios] Fix interpreter NullReferenceException with Vector<T> on x64 ios simulator Jun 4, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

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 adjusts CoreCLR’s CPU feature initialization so that when execution is interpreter-only (either DOTNET_InterpMode=3 or when the runtime is built without dynamic code compilation/JIT), Vector<T> is constrained to 128-bit on x86/x64. This prevents the runtime from advertising/selecting 256-bit Vector<T> on AVX2-capable x64 machines in configurations where the interpreter can only handle 128-bit vectors.

Changes:

  • Detect “interpreter-only” operation as (InterpMode == 3) || !FEATURE_DYNAMIC_CODE_COMPILED.
  • Clamp EXTERNAL_MaxVectorTBitWidth to 128 in interpreter-only mode to prevent enabling InstructionSet_VectorT256/512.
  • Clamp EXTERNAL_PreferredVectorBitWidth to 128 in interpreter-only mode to keep vector-width preference consistent with interpreter constraints.
Show a summary per file
File Description
src/coreclr/vm/codeman.cpp Updates EEJitManager::SetCpuInfo() to force 128-bit Vector<T> sizing when the interpreter is the only execution engine (including no-JIT builds).

Copilot's findings

  • Files reviewed: 1/1 changed files
  • Comments generated: 0

@kotlarmilos kotlarmilos added this to the 11.0.0 milestone Jun 4, 2026
@kotlarmilos kotlarmilos added the os-ios Apple iOS label Jun 4, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to 'os-ios': @vitek-karas, @kotlarmilos, @steveisok, @akoeplinger
See info in area-owners.md if you want to be subscribed.

Comment thread src/coreclr/vm/codeman.cpp Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/coreclr/tools/Common/InstructionSetHelpers.cs Outdated
On interpreter-only runtimes (no JIT), R2R native code is the only
executable form of a method. When the image was compiled with
--strip-il-bodies and an eager fixup fails (e.g. an instruction-set
check), R2R is disabled and the interpreter runs the throw stub left in
place of the IL, which surfaces as an opaque self-recursing stack
overflow. Fail fast with a clear message instead. Runtimes with a JIT
already reject stripped images at load, so this path is only reachable
when there is no recovery option.

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

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.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 2

Comment thread src/coreclr/vm/readytoruninfo.h Outdated
Comment thread src/coreclr/vm/codeman.cpp Outdated
Comment thread src/coreclr/tools/Common/InstructionSetHelpers.cs
iOS and tvOS devices are ARM-only, so the x86/x64 branch is never reached
for TargetOS.iOS/tvOS; only the simulator targets run x64 (Intel/Rosetta)
and need the x86-64-v2 baseline.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The READYTORUN_FLAG_STRIPPED_IL_BODIES flag is emitted on each component
assembly's own R2R header (RewriteComponentFile), not on the composite
global header, so read it from m_pHeader like IsPartial() and the existing
check in ReadyToRunInfo::InitializeForModule. Reading the composite header
would miss stripped IL bodies for composite components and skip the fatal
check on no-JIT builds.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 5, 2026 10:22
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kotlarmilos kotlarmilos changed the title [clr-ios] Fix interpreter NullReferenceException with Vector<T> on x64 ios simulator [clr-ios] Fix Vector<T> width and R2R AVX baseline mismatch on x64 iOS/tvOS simulators Jun 5, 2026

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.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 0 new

Comment thread src/coreclr/vm/codeman.cpp Outdated
Comment thread src/coreclr/vm/codeman.cpp Outdated
kotlarmilos and others added 2 commits June 5, 2026 17:35
The first maxVectorTBitWidth check already pins Vector<T> to 128-bit, so
VectorT256/VectorT512 are never set on interpreter-only runtimes. The
preferredVectorBitWidth block only controls the JIT's internal preferred
vector width, which is irrelevant when the interpreter is the only engine.

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

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.

Copilot's findings

  • Files reviewed: 4/4 changed files
  • Comments generated: 0 new

@janvorli janvorli 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 modulo a nit to consider. Thank you!

Comment thread src/coreclr/vm/readytoruninfo.h Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kotlarmilos kotlarmilos enabled auto-merge (squash) June 8, 2026 14:44
@kotlarmilos kotlarmilos merged commit fc3e8ea into dotnet:main Jun 8, 2026
113 checks passed
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.

NullReferenceException in System.Numerics.Vector.get_IsHardwareAccelerated() Stackoverflow at startup with CoreCLR on ios simulator x64

6 participants