JIT: Assert OperIs(GT_LCL_VAR, GT_LCL_FLD, GT_PHI_ARG, ... during 'Forward Substitution' #134818
Copy link
Copy link
Closed
Labels
area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Milestone
Description
Activity
- addedarea-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
on Sep 28, 2026 dotnet-policy-service commented
on Sep 28, 2026 ContributorMore actionsTagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.- added a commit that references this issue
on Oct 1, 2026
Metadata
Metadata
Assignees
Labels
area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMICLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
Assert on X86 with
DOTNET_TieredCompilation = "0".Repro:
Assert failure(PID 34112 [0x00008540], Thread: 3056 [0x0bf0]): Assertion failed 'OperIs(GT_LCL_VAR, GT_LCL_FLD, GT_PHI_ARG, GT_STORE_LCL_VAR, GT_STORE_LCL_FLD, GT_LCL_ADDR)' in 'TestClass:Method0()' during 'Forward Substitution'.
AI Notes:
Root cause —
src/coreclr/jit/forwardsub.cpp:fgIsCheapReorderableAddressTree(L123) gates ontree->TypeIs(TYP_BYREF, TYP_I_IMPL). On a 32-bit targetTYP_I_IMPL == TYP_INT, so an ordinaryintLCL_VARpasses andisCheapAddressTreeis set at L690.multiUse = true(L710).varTypeIsSmall(varDsc) && fgCastNeeded(...)and re-wrapsfwdSubNodein aGT_CAST— aftermultiUsewas already decided (JitDump:[adding cast for small-typed local]).fgForwardSubMultiUse(L1036) -> L232 doesgtPeelFieldAddrs(fwdSubNode)->AsLclVarCommon().gtPeelFieldAddrsonly peelsGT_FIELD_ADDR, so theGT_CASTreachesAsLclVarCommon()and asserts.On 64-bit,
TYP_I_IMPL == TYP_LONGrejects theintlocal at step 1; aLONG/BYREFvalue can never be the data of a store to a small local, so steps 1 and 3 are mutually exclusive.Confirmed via JitDump:
[adding cast for small-typed local]is the last line emitted before every crash.Introduced by #133703, which replaced a guarded node walk with an unguarded
gtPeelFieldAddrs(...)->AsLclVarCommon().[!NOTE]
The root-cause analysis in this issue was produced with GitHub Copilot