Skip to content

Fix discarding of NRE's when unboxing nullables in Mono and JIT - #133351

Merged
jakobbotsch merged 3 commits into
dotnet:mainfrom
jakobbotsch:fix-133207
Sep 8, 2026
Merged

jakobbotsch merged 3 commits into
dotnet:mainfrom
jakobbotsch:fix-133207

Conversation

@jakobbotsch

@jakobbotsch jakobbotsch commented Sep 7, 2026

Copy link
Copy Markdown
Member

VN-based constant folding did not preserve exceptions from the root node. For GetType folding, that results in discarding an explicit nullcheck.

Retain throwing roots when their VN exception sets are not covered by their operands. Fold unused GetType operations to null checks through shared side-effect extraction, and add a targeted nullable GetType regression test.

Mono had a similar issue for nullables only, which was fixed in #132732 but later reverted. This PR includes that fix.

Fix #133207

Retain throwing roots when their VN exception sets are not covered by their operands. Fold unused GetType operations to null checks through shared side-effect extraction, and add a targeted nullable GetType regression test.

Fixes dotnet#133207.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f9c8af88-4173-4ead-99f9-50375606ef4a
@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 Sep 7, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 5 pipeline(s).
11 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

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

Comment thread src/tests/JIT/Regression/JitBlue/Runtime_133207/Runtime_133207.cs
Restore the Mono interpreter GetType fix without duplicating the JitBlue regression. Remove debug destruction of roots that assertion propagation may retain for side effects.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f9c8af88-4173-4ead-99f9-50375606ef4a
@jakobbotsch jakobbotsch changed the title JIT: preserve root exceptions during VN constant folding Fix discarding of NRE's when unboxing nullables in Mono and JIT Sep 7, 2026
@jakobbotsch

Copy link
Copy Markdown
Member Author

/azp run runtime-coreclr superpmi-diffs

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).

@jakobbotsch

Copy link
Copy Markdown
Member Author

/ba-g Failure is #130439

@jakobbotsch
jakobbotsch marked this pull request as ready for review September 8, 2026 11:38
Copilot AI lite review requested due to automatic review settings September 8, 2026 11:38
@jakobbotsch

Copy link
Copy Markdown
Member Author

cc @dotnet/jit-contrib PTAL @EgorBo

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 5 pipeline(s).
11 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

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.

🟡 Changes recommended

The new exception-set subset logic unions operand VNs without guarding against undefined VN pairs, which can trigger debug asserts/crashes in some loop/PHI scenarios.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR fixes a JIT and Mono interpreter optimization bug where VN-based folding (notably GetType folding on boxed nullables) could drop required faulting behavior, leading to missing NullReferenceExceptions. It also adds a targeted JIT regression test to prevent recurrence.

Changes:

  • Update JIT VN-based constant folding to retain “throwing roots” when their exception sets aren’t covered by operands, and improve side-effect extraction so unused GetType can be reduced to a null-check.
  • Reapply the Mono interpreter fix to avoid optimizing box Nullable<T>; call GetType() into a constant type lookup.
  • Add a regression test for Nullable<T>.GetType() behavior (throws on null; returns underlying type when non-null).
File summaries
File Description
src/coreclr/jit/assertionprop.cpp Adjust VN-based folding to decide when to preserve root side effects based on exception-set coverage.
src/coreclr/jit/gentree.cpp Add helper to turn unused GetType into a NULLCHECK via shared side-effect extraction.
src/coreclr/jit/compiler.h Declare the new side-effect extraction helper on Compiler.
src/mono/mono/mini/interp/transform.c Disable the box; GetType optimization for nullable types in the interpreter.
src/tests/JIT/Regression/JitBlue/Runtime_133207/Runtime_133207.cs Add xUnit regression coverage for nullable GetType throwing/returning behavior.
src/tests/JIT/Regression/Regression_ro_2.csproj Include the new regression test in the JIT regression project.
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread src/coreclr/jit/assertionprop.cpp
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 8, 2026 12:04

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.

🔵 Needs a closer look

It changes JIT optimization and side-effect extraction behavior in broadly-used code paths, so it warrants final maintainer review despite the added regression coverage.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Comment thread src/coreclr/jit/assertionprop.cpp
@jakobbotsch

Copy link
Copy Markdown
Member Author

Minor diffs.

@jakobbotsch
jakobbotsch merged commit bc3f1a5 into dotnet:main Sep 8, 2026
173 of 177 checks passed
@jakobbotsch

Copy link
Copy Markdown
Member Author

/backport to release/11.0

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Started backporting to release/11.0 (link to workflow run)

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

@jakobbotsch backporting to release/11.0 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git cherry-pick bc3f1a51d9fad655cb3fbf28b94e98fceba7b890

Auto-merging src/coreclr/jit/assertionprop.cpp
Auto-merging src/coreclr/jit/compiler.h
Auto-merging src/coreclr/jit/gentree.cpp
Auto-merging src/tests/JIT/Regression/Regression_ro_2.csproj
CONFLICT (content): Merge conflict in src/tests/JIT/Regression/Regression_ro_2.csproj
error: could not apply bc3f1a51d9f... Fix discarding of NRE's when unboxing nullables in Mono and JIT (#133351)
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".
hint: Disable this message with "git config set advice.mergeConflict false"


$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch

Applying: JIT: preserve root exceptions during VN constant folding
Using index info to reconstruct a base tree...
M	src/coreclr/jit/assertionprop.cpp
M	src/coreclr/jit/compiler.h
M	src/coreclr/jit/gentree.cpp
M	src/tests/JIT/Regression/Regression_ro_2.csproj
Falling back to patching base and 3-way merge...
Auto-merging src/coreclr/jit/assertionprop.cpp
Auto-merging src/coreclr/jit/compiler.h
Auto-merging src/coreclr/jit/gentree.cpp
Auto-merging src/tests/JIT/Regression/Regression_ro_2.csproj
CONFLICT (content): Merge conflict in src/tests/JIT/Regression/Regression_ro_2.csproj
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0001 JIT: preserve root exceptions during VN constant folding
Error: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

@lewing lewing mentioned this pull request Sep 9, 2026
6 tasks
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 12.0-preview1 milestone Sep 9, 2026
JulieLeeMSFT pushed a commit that referenced this pull request Sep 9, 2026
…o and JIT (#133477)

Backport of #133351 to release/11.0

## Customer Impact

- [ ] Customer reported
- [x] Found internally

Mono and the JIT may discard a null-check of `x` when folding
`x.GetType()` to a type object directly. If `x` is null the program then
does not throw when it should.

## Regression

- [ ] Yes
- [x] No

## Testing

Regression test added. 

## Risk

Low.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ebafd673-83d3-4ca7-91c4-8e4b5642d048
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.

[ci-scan] Test failure: JitTest_Directed_nullabletypes_gettype.P.BoxedNullableGetType

4 participants