Skip to content

JIT: Transform SELECT to (folded) bitwise op#128295

Open
BoyBaykiller wants to merge 2 commits into
dotnet:mainfrom
BoyBaykiller:select-to-folded-bitwise-op
Open

JIT: Transform SELECT to (folded) bitwise op#128295
BoyBaykiller wants to merge 2 commits into
dotnet:mainfrom
BoyBaykiller:select-to-folded-bitwise-op

Conversation

@BoyBaykiller
Copy link
Copy Markdown
Contributor

Fix #123291

  1. Add canonicalization of CNS to right: SELECT(x == 0, 1, x > 0) -> SELECT(x != 0, x > 0, 1)
  2. Add transform to bitwise op: SELECT(x != 0, x > 0, 1) -> (x == 0) | (x > 0)
  3. Add gtFoldAndOrXor to fuse cmps: (x == 0) | (x > 0) -> x >= 0

This overlaps with work that optimizeBools does already. But I think handling it in if-conversion like this is overall better. Perhaps in the future (with the help of this PR and more...) we don't need optimizeBools at all.

I added a general gtFoldAndOrXor to gtFoldExpr to fuse the cmps. I didn't add it to morph (e.g fgOptimizeCommutativeArithmetic) because 1. I am not allowed to call that from if-conversion and 2. my understanding of @EgorBo is that we are moving things like this to gtFoldExpr anyway.

Diffs on XARCH look worse because of https://discord.com/channels/143867839282020352/312132327348240384/1502728076243767439

Note the current costing leads to us frequently rejecting cases, for example:
return x == 3 && y == 3; would be transformed to (x == 3 & y == 3) which optimizeBools doesnt do either, but we get:
Skipping if-conversion that will evaluate RHS unconditionally at costs 8,1 - it only allows up to 7.

* add SELECT to bitwise transform
* add gtFoldAndOrXor and do simple cmp fusion in it (to produce final x >= 0)
@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 17, 2026
@dotnet-policy-service dotnet-policy-service Bot added the community-contribution Indicates that the PR has been added by a community member label May 17, 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.

@EgorBo
Copy link
Copy Markdown
Member

EgorBo commented May 17, 2026

Diffs on XARCH look worse because of https://discord.com/channels/143867839282020352/312132327348240384/1502728076243767439

this link is not working for me. What is the reason behind bad regressions in both size and perfscore on x64?

Comment thread src/coreclr/jit/gentree.cpp Outdated
}

if (fusedCmp != GT_NONE && GenTree::Compare(op1->gtGetOp1(), op2->gtGetOp1()) &&
GenTree::Compare(op1->gtGetOp2(), op2->gtGetOp2()))
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.

you need to check side-effects here, otherwise you're potentially removing one

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I limited it to op->OperIsAnyLocal() || op->OperIsConst() (in my new commit) because I need to do that anyway because of GenTree::Compare. With that check in place, do I still need to check for any side effects?

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.

Jit: Missing folding some compares in optimizebools

2 participants