Uh oh!
There was an error while loading. Please reload this page.
JIT: add NativeAOT support for non-shared GVM devirtualization - #130202
Conversation
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
There was a problem hiding this comment.
Pull request overview
Enables NativeAOT generic virtual method (GVM) devirtualization by preserving the helper-call-shaped indirection target long enough for the importer’s devirtualization logic to recognize it, while still supporting NativeAOT fat-pointer lowering later during indirect-call transformation.
Changes:
- Stop spilling NativeAOT GVM
ldvirtftntargets to a temp in the importer; instead only mark calls as fat-pointer candidates. - In indirect-call transformation, for generic-virtual fat-pointer candidates, split/spill as needed and then materialize the function pointer into a temp local before expanding the fat-pointer control-flow.
- Ensure fat-pointer-candidate marking is cleared when a call is devirtualized to a direct call; additionally, skip guarded devirtualization for generic-virtual calls.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/coreclr/jit/indirectcalltransformer.cpp | Adds late temp materialization of GVM fat-pointer call targets (post-import) prior to fat-pointer expansion. |
| src/coreclr/jit/importercalls.cpp | Removes early temp spill for NativeAOT GVM ldvirtftn calls; blocks GDV for generic-virtual calls; clears fat-pointer candidate on devirtualization. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
It's hitting IL scanner issues like cc: @MichalStrehovsky does this ring a bell? UPDATE: addressed in 2291537 |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
MichalStrehovsky
commented
Jul 8, 2026
/azp run runtime-nativeaot-outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
MichalStrehovsky
left a comment
There was a problem hiding this comment.
The CorInfoImpl.cs change looks good to me!
hez2010
commented
Jul 9, 2026
Test failures are unrelated. @jakobbotsch PTAL. |
hez2010
commented
Jul 14, 2026
CI failures seem unrelated. |
MichalStrehovsky
commented
Jul 14, 2026
/azp run runtime-nativeaot-outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
hez2010
commented
Jul 14, 2026
naot outerloop failure seems to be #130647? |
jakobbotsch
commented
Jul 14, 2026
/ba-g Failure was #130647 |
Uh oh!
There was an error while loading. Please reload this page.
When resolving an instantiated interface GVM, we passed down the method generic instantiation. However, interface slot selection needs to be done on the GVM definition, otherwise it could resolve to whatever the first compatible interface slot we saw. This can produce the incorrect devirtualized target when a type implements an interface GVM with multiple variant-compatible instantiations. Fixed it by stripping the method instantiation before resolving the interface slot. The CoreCLR native type system already handles such cases well so we don't have any issue there. Found this issue while I was working on GVM devirt for NAOT in #130202. See added tests for repro: previously it failed for the `CallOnBase` cases. Tests are added to both the managed type system and the normal JIT tests to prevent future regressions in either side. cc: @MichalStrehovsky
Under NativeAOT, only mark the fat pointer calls but defer the transformation until we are going to perform indirect calls transform, so that the JIT can recognize the tree for GVM devirtualization.
Unfortunately, we are not able to support late devirtualization and guarded devirtualization because fat pointer call transformation happens too early.
Shared GVMs are also not supported due to IL scanner limitations.
Example:
Before:
After:
Contributes to #112596