Skip to content

Improve fgGetStaticFieldSeqAndAddress and fgValueNumberConstLoad#128638

Closed
EgorBo wants to merge 2 commits into
dotnet:mainfrom
EgorBo:improve-const-load-vn
Closed

Improve fgGetStaticFieldSeqAndAddress and fgValueNumberConstLoad#128638
EgorBo wants to merge 2 commits into
dotnet:mainfrom
EgorBo:improve-const-load-vn

Conversation

@EgorBo
Copy link
Copy Markdown
Member

@EgorBo EgorBo commented May 27, 2026

No description provided.

Copilot AI review requested due to automatic review settings May 27, 2026 11:01
@EgorBo
Copy link
Copy Markdown
Member Author

EgorBo commented May 27, 2026

@MihuBot

@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.

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 updates JIT value-numbering helpers in valuenum.cpp to better recognize static-field address patterns (including cases where constant offsets are hidden in VNs) and to widen constant-load folding opportunities during value numbering.

Changes:

  • Refactors fgGetStaticFieldSeqAndAddress into an instance method and enhances it to use conservative-normal VNs plus ValueNumStore::PeelOffsets to recover additional constant offsets.
  • Updates constant-load VN folding (fgValueNumberConstLoad) to preserve exception sets when applying folded VNs and to attempt folding from additional address forms (including icon handles).
  • Adjusts some static-field content reads to pass ignoreMovableObjects=false and updates call sites to the new fgGetStaticFieldSeqAndAddress signature.

Reviewed changes

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

File Description
src/coreclr/jit/valuenum.cpp Enhances static-field address detection via conservative VNs + VN offset peeling; widens const-load VN folding and preserves exception sets when applying folded VNs.
src/coreclr/jit/compiler.h Changes fgGetStaticFieldSeqAndAddress declaration to instance method and adds a new VN-based folding method declaration.

Comment thread src/coreclr/jit/valuenum.cpp Outdated
}
*ppValue = new (alloc) uint8_t[(size_t)size];
return info.compCompHnd->getStaticFieldContent(fld, *ppValue, size, (int)byteOffset);
return info.compCompHnd->getStaticFieldContent(fld, *ppValue, size, (int)byteOffset, false);
Comment thread src/coreclr/jit/valuenum.cpp Outdated
Comment on lines 12849 to 12854
// Pass ignoreMovableObjects=false so we can fold ref-typed static readonly fields
// even when the referenced object lives on the regular (movable) heap. The JIT-side
// handle returned by the runtime keeps the object alive for the lifetime of the
// compiled code.
if (info.compCompHnd->getStaticFieldContent(fieldHandle, buffer, size, (int)byteOffset, false))
{
Comment thread src/coreclr/jit/compiler.h Outdated
PhaseStatus fgVNBasedIntrinsicExpansion();
bool fgVNBasedIntrinsicExpansionForCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
bool fgVNBasedIntrinsicExpansionForCall_ReadUtf8(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
bool fgVNBasedFoldSequenceEqualCall(BasicBlock** pBlock, Statement* stmt, GenTreeCall* call);
The Copilot PR review caught two issues that I have confirmed by adding a
local regression test (movable static readonly object reference):

1. Passing ignoreMovableObjects=false to getStaticFieldContent for a
   ref-typed static field returns a tagged JIT-side OBJECTHANDLE rather
   than the field's actual reference value. The JIT then folded that
   value as a plain immediate, but for non-frozen (movable) objects the
   GC moves the underlying object so the immediate becomes stale.
   Reverting both call sites to the default (ignoreMovableObjects=true)
   restores the safe behavior: folding only succeeds when the object is
   in a frozen segment.

2. Drops the orphan fgVNBasedFoldSequenceEqualCall declaration from
   compiler.h; no implementation/callers exist for it.

Local validation:
* Hand-crafted test with a static readonly object Obj = new object()
  and Bench.Test(o) => o == Obj returned false even when called with
  Bench.Obj before the fix; passes after.
* SPMI replay clean on benchmarks.run, coreclr_tests, libraries.crossgen2,
  libraries.pmi (no asserts).
* SPMI asmdiffs: no asm diffs on any of those four collections, confirming
  the remaining VN refactor is functionally equivalent to main.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@EgorBo EgorBo force-pushed the improve-const-load-vn branch from 2ef3f0c to 3ef81f2 Compare May 27, 2026 15:29
@EgorBo
Copy link
Copy Markdown
Member Author

EgorBo commented May 27, 2026

@MihuBot

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants