Skip to content

JIT: model the signed Log2 fallback as throwing - #135485

Merged
EgorBo merged 2 commits into
dotnet:mainfrom
EgorBo:jit-fix-133965
Oct 10, 2026
Merged

EgorBo merged 2 commits into
dotnet:mainfrom
EgorBo:jit-fix-133965

Conversation

@EgorBo

@EgorBo EgorBo commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Signed int.Log2/long.Log2 are imported as
x < 0 ? INTRINSIC(Log2, x) : lzcnt-based result, where the intrinsic fallback is later rewritten into the throwing managed call. The fallback node only had a hand-set GTF_CALL; OperExceptions reported no exceptions for it and side effect checks only treat real calls as calls. So when the result was unused, the dead store containing the fallback was removed along with the ArgumentOutOfRangeException.

Report the fallback intrinsic as possibly throwing (OperExceptions, GTF_EXCEPT), and give it an opaque exception set in value numbering, as the NamedIntrinsic guidance for throwing GT_INTRINSICs requires.

Keeping the fallback exposed a latent bug in fgExpandQmarkStmt: for qmarks with only a then arm, the condition is reversed but the then/else likelihoods were assigned to the opposite edges, producing inconsistent profile data when the then arm is rare. Assign them to the correct edges.

No asm diffs

Fixes #133965

PR description:
<!-- -->

Signed `int.Log2`/`long.Log2` are imported as
`x < 0 ? INTRINSIC(Log2, x) : lzcnt-based result`, where the intrinsic fallback
is later rewritten into the throwing managed call. The fallback node only had
a hand-set `GTF_CALL`; `OperExceptions` reported no exceptions for it and side
effect checks only treat real calls as calls. So when the result was unused,
the dead store containing the fallback was removed along with the
`ArgumentOutOfRangeException`.

Report the fallback intrinsic as possibly throwing (`OperExceptions`,
`GTF_EXCEPT`), and give it an opaque exception set in value numbering, as the
`NamedIntrinsic` guidance for throwing `GT_INTRINSIC`s requires.

Keeping the fallback exposed a latent bug in `fgExpandQmarkStmt`: for qmarks
with only a then arm, the condition is reversed but the then/else likelihoods
were assigned to the opposite edges, producing inconsistent profile data when
the then arm is rare. Assign them to the correct edges.

No asm diffs in libraries.pmi (windows-x64).

Add a single-file regression for used and unused signed Log2 results.

Fixes dotnet#133965

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 15ca58a5-0ca4-4d38-8775-43e1c7aa8150
@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 Oct 9, 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.

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

Regression coverage omits nint.Log2, which uses the same signed fallback path.

1 open finding
What changed in this PR

Fixes signed Log2 exception handling when the result is discarded and corrects associated qmark profile likelihoods.

Changes:

  • Marks signed Log2 fallback intrinsics as throwing.
  • Preserves exceptions during value numbering.
  • Adds regression coverage and corrects qmark edge likelihoods.
File Description
src/​coreclr/​jit/​gentree.cpp Reports Log2 fallback exceptions.
src/​coreclr/​jit/​importercalls.cpp Adds GTF_EXCEPT to the fallback.
src/​coreclr/​jit/​morph.cpp Corrects qmark edge likelihood assignment.
src/​coreclr/​jit/​valuenum.cpp Models an opaque exception set.
src/​tests/​JIT/​Regression_ro_2/​Runtime_133965.cs Tests discarded signed Log2 results.

🧠 Review effort: Balanced

Comment thread src/tests/JIT/Regression_ro_2/Runtime_133965.cs
Added TestNative method to test Log2 for nint type.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@EgorBo

EgorBo commented Oct 9, 2026

Copy link
Copy Markdown
Member Author

PTAL @dotnet/jit-contrib

@JulieLeeMSFT JulieLeeMSFT left a comment

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.

LGTM. The signed log2 fallback seems correct.

@EgorBo
EgorBo enabled auto-merge (squash) October 10, 2026 16:45
@EgorBo

EgorBo commented Oct 10, 2026

Copy link
Copy Markdown
Member Author

/ba-g timeout

@EgorBo
EgorBo merged commit 0d4ee43 into dotnet:main Oct 10, 2026
144 of 147 checks passed
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: (bug) signed Log2 intrinsic drops ArgumentOutOfRangeException when the result is unused

3 participants