Skip to content

JIT: If-convert to x +/- cond and fold 0/1 compares - #135757

Open
am11 wants to merge 2 commits into
dotnet:mainfrom
am11:feature/jit/ifconv-select-arith
Open

am11 wants to merge 2 commits into
dotnet:mainfrom
am11:feature/jit/ifconv-select-arith

Conversation

@am11

@am11 am11 commented Oct 14, 2026

Copy link
Copy Markdown
Member

Produce the "x +/- compare" shape that lowering turns into adc/sbb/cinc
in more places:

  • If-conversion turns SELECT(cond, x +/- 1, x) and SELECT(cond, k + 1,
    k) into "x +/- cond" and "k + cond" on all targets when cond is a
    compare that lowering can consume as a carry (== 0, != 0 and unsigned
    compares). Inside loops, if-conversion is now allowed when the result
    is such arithmetic instead of a SELECT, so "if (a[i] < p) count++"
    becomes "cmp; adc" instead of a branch.
  • Operands without side effects or memory reads may be evaluated
    unconditionally even when the condition has ordering side effects.
  • If-converted values stored to a temp whose only use adds or subtracts
    it are forwarded into that use, e.g. "num + (r ? 0 : -1)" becomes
    "cmp r, 1; sbb num, 0" on x64.
  • Value numbering can now tell when a value is always 0 or 1: compares,
    0/1 constants, AND/OR/XOR and casts of such values, and phis of them.
    VN-based folding uses this to fold "x != 0" to "x" and "x == 0" to
    "x ^ 1". Values loaded from memory are not affected, so bools holding
    other non-zero values are still handled as ECMA requires.

Note: #135678's commit is included here.

@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 14, 2026
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label Oct 14, 2026
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 8 pipeline(s).
8 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.

am11 added 2 commits October 17, 2026 00:45
Produce the "x +/- compare" shape that lowering turns into adc/sbb/cinc
in more places:

- If-conversion turns SELECT(cond, x +/- 1, x) and SELECT(cond, k + 1,
  k) into "x +/- cond" and "k + cond" on all targets when cond is a
  compare that lowering can consume as a carry (== 0, != 0 and unsigned
  compares). Inside loops, if-conversion is now allowed when the result
  is such arithmetic instead of a SELECT, so "if (a[i] < p) count++"
  becomes "cmp; adc" instead of a branch.
- Operands without side effects or memory reads may be evaluated
  unconditionally even when the condition has ordering side effects.
- If-converted values stored to a temp whose only use adds or subtracts
  it are forwarded into that use, e.g. "num + (r ? 0 : -1)" becomes
  "cmp r, 1; sbb num, 0" on x64.
- Value numbering can now tell when a value is always 0 or 1: compares,
  0/1 constants, AND/OR/XOR and casts of such values, and phis of them.
  VN-based folding uses this to fold "x != 0" to "x" and "x == 0" to
  "x ^ 1". Values loaded from memory are not affected, so bools holding
  other non-zero values are still handled as ECMA requires.
@tannergooding

Copy link
Copy Markdown
Member

There's also #134039 which might overlap and or benefit from the same (and I have my own variant of the optimization too, which I've not looked at in a bit but which I just rebased on dotnet/main and had AI do a fresh pass over: https://github.com/tannergooding/runtime/tree/tannergooding-jit-adc-sbb-carry-pattern).

This is a general pattern and setup that could be broadly impactful with the right overall handling/setup and might warrant some cross scenario measurements and comparisons

@am11

am11 commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

Sounds good. We could get opus/fable type of model to go over these three/four overlapping PRs and gather valuable parts and supersede. I asked the model to lean towards fewer diffs. In its footnotes, it said something like "there are more phases/places in JIT where this pattern could be applied".

This branch has not been deployed

No deployments
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 community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants