Skip to content

JIT: Assert OperIs(GT_LCL_VAR, GT_LCL_FLD, GT_PHI_ARG, ... during 'Forward Substitution' #134818

Description

@dhartglassMSFT

Assert on X86 with DOTNET_TieredCompilation = "0".

Repro:

using System;

public class TestClass
{
    static sbyte s_sink;

    public static void Method0()
    {
        sbyte sb = 0;
        s_sink = (sbyte)((sbyte)(sb -= sb) - (sbyte)(sb -= sb));
    }

    public static int Main()
    {
        Method0();
        Console.WriteLine(s_sink);
        return 100;
    }
}

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:

  1. fgIsCheapReorderableAddressTree (L123) gates on tree->TypeIs(TYP_BYREF, TYP_I_IMPL). On a 32-bit target TYP_I_IMPL == TYP_INT, so an ordinary int LCL_VAR passes and isCheapAddressTree is set at L690.
  2. A non-last use in the next statement sets multiUse = true (L710).
  3. L1028 then sees varTypeIsSmall(varDsc) && fgCastNeeded(...) and re-wraps fwdSubNode in a GT_CAST — after multiUse was already decided (JitDump: [adding cast for small-typed local]).
  4. fgForwardSubMultiUse (L1036) -> L232 does gtPeelFieldAddrs(fwdSubNode)->AsLclVarCommon(). gtPeelFieldAddrs only peels GT_FIELD_ADDR, so the GT_CAST reaches AsLclVarCommon() and asserts.

On 64-bit, TYP_I_IMPL == TYP_LONG rejects the int local at step 1; a LONG/BYREF value 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

Activity

  1. added
    area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI
    on Sep 28, 2026
  2. added this to the 12.0.0 milestone on Sep 28, 2026
  3. dotnet-policy-service commented on Sep 28, 2026

    @dotnet-policy-service
    Contributor

    Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
    See info in area-owners.md if you want to be subscribed.

  4. jakobbotsch commented on Sep 29, 2026

    @jakobbotsch
    Member

    Note that #133703 was backported to .NET 11 via #134349, so the fix here should likely also go into .NET 11.

  5. dhartglassMSFT commented on Sep 30, 2026

    @dhartglassMSFT
    ContributorAuthor

    Note that #133703 was backported to .NET 11 via #134349, so the fix here should likely also go into .NET 11.

    good point, fix is small I'll push it tomorrow

  6. added a commit that references this issue on Oct 1, 2026
    c873bfd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions