Skip to content

JIT: bail on flipping post-layout JTRUE when reversal needs new IR#127746

Open
Copilot wants to merge 6 commits into
mainfrom
copilot/fix-assertion-failure-jit
Open

JIT: bail on flipping post-layout JTRUE when reversal needs new IR#127746
Copilot wants to merge 6 commits into
mainfrom
copilot/fix-assertion-failure-jit

Conversation

Copilot AI commented May 4, 2026

Copy link
Copy Markdown
Contributor

optOptimizePostLayout runs after LSRA and called gtReverseCond, which can fall back to wrapping the operand in a fresh GT_EQ(tree, 0). The new GT_INT_CON child is never inserted into the LIR, tripping found use of a node that is not in the LIR sequence in checked builds (reported by Fuzzlyn on linux-arm32). The fallback was also reached whenever LSRA inserted a GT_COPY/GT_RELOAD on top of the JTRUE operand, since the wrapper is not itself a comparison.

Description

  • gentree.cpp / compiler.h — Extract gtTryReverseCond(GenTree*) -> bool that reverses compares, JCC/SETCC, JCMP/JTEST, and integral constants in place. gtReverseCond becomes a thin wrapper that adds the GT_EQ(tree, 0) fallback when in-place reversal isn't possible, preserving semantics for all existing callers.
  • optimizer.cpp — In optOptimizePostLayout, peel GT_COPY/GT_RELOAD off the GT_JTRUE operand via gtSkipReloadOrCopy(), then use gtTryReverseCond and skip flipping the block if it returns false rather than mutating the LIR.
  • src/tests/JIT/Regression/JitBlue/Runtime_127745 — Added a JIT regression test using the reduced repro from the Fuzzlyn report: a method with a do-while loop, try-finally, and a bitwise-OR of two comparisons that produces a SETCC result under a JTRUE.
GenTree* cond = test;
if (test->OperIs(GT_JTRUE))
{
    cond = test->gtGetOp1()->gtSkipReloadOrCopy();
}

if (!gtTryReverseCond(cond))
{
    continue;
}

Copilot AI self-assigned this May 4, 2026
Copilot AI review requested due to automatic review settings May 4, 2026 12:52
Copilot AI removed the request for review from Copilot May 4, 2026 12:52
Copilot AI requested review from Copilot and removed request for Copilot May 4, 2026 13:00
Copilot AI changed the title [WIP] Fix assertion failure in JIT during optimize post-layout JIT: bail on flipping post-layout JTRUE when reversal needs new IR May 4, 2026
Copilot AI requested a review from jakobbotsch May 4, 2026 13:02
Comment thread src/coreclr/jit/gentree.cpp
Copilot AI requested review from Copilot and jakobbotsch and removed request for Copilot May 4, 2026 13:10
@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label May 4, 2026
@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.

Copilot AI review requested due to automatic review settings May 27, 2026 06:54

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 late (post-LSRA) block-flipping in the CoreCLR JIT to avoid creating new IR nodes after LIR has been formed, by introducing an in-place-only condition reversal helper. This prevents LIR integrity failures when condition reversal would otherwise require synthesizing new IR (e.g., wrapping a non-compare in == 0) and also handles GT_COPY/GT_RELOAD wrappers introduced by LSRA on GT_JTRUE operands.

Changes:

  • Add Compiler::gtTryReverseCond(GenTree*) -> bool to reverse supported conditions in-place (relops, JCC/SETCC, JCMP/JTEST, integral constants) without allocating new IR.
  • Make gtReverseCond a thin wrapper that preserves existing behavior by falling back to creating GT_EQ(tree, 0) when in-place reversal isn’t possible.
  • Update optOptimizePostLayout to (1) peel GT_COPY/GT_RELOAD off GT_JTRUE operands and (2) skip flipping a block when in-place reversal isn’t possible, rather than mutating LIR.

Reviewed changes

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

File Description
src/coreclr/jit/optimizer.cpp Switch post-layout flipping to use in-place-only reversal and bail out when reversal would require new IR; skip LSRA GT_COPY/GT_RELOAD wrappers for GT_JTRUE.
src/coreclr/jit/gentree.cpp Introduce gtTryReverseCond and refactor gtReverseCond to use it, keeping the existing fallback semantics for other callers.
src/coreclr/jit/compiler.h Declare the new gtTryReverseCond helper on Compiler.

@jakobbotsch

Copy link
Copy Markdown
Member

cc @dotnet/jit-contrib PTAL @dhartglassMSFT

@dhartglassMSFT

Copy link
Copy Markdown
Contributor

@copilot add the bug repro from 127745 as a JIT regression test

… assert)

Co-authored-by: dhartglassMSFT <248563697+dhartglassMSFT@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot June 17, 2026 21:51

Copilot AI commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

@copilot add the bug repro from 127745 as a JIT regression test

Done in the latest commit. Added src/tests/JIT/Regression/JitBlue/Runtime_127745/Runtime_127745.cs with the reduced repro from the issue (do-while loop, try-finally, and the bitwise-OR condition that produces a SETCC). The test is registered in Regression_ro_2.csproj. Since the regression was a compile-time JIT assertion rather than wrong output, the test calls the method and catches the NullReferenceException from the null static fields.

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.

I think it is unlikely that this test reproduces the original problem. Fuzzlyn found that we need a collectible ALC for the test (that impacts our codegen for static access), and that's a bit of a pain to set up correctly in the regression tests. I would probably just skip the regression test and rely on the Fuzzlyn testing.

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.

sounds good, change LGTM, if you need another signoff after presumably removing the cs and csproj changes let me know

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.

JIT: Assertion failed found use of a node that is not in the LIR sequence during 'Optimize post-layout'

4 participants