This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Add transforms for `(max/min (xor X, Pow2), X)` -> `(and/or X, Pow2/~Pow2)`
ClosedPublic

Authored by goldstein.w.n on Feb 22 2023, 5:20 PM.

Details

Summary

X ^ Pow2 is guranteed to flip one bit. We can use this to speedup
max/min by just selecting X with/without (or/andnot) the flipped bit
respectively.

Alive2 Links:
smax-neg: https://alive2.llvm.org/ce/z/j3QYFs
smin-neg: https://alive2.llvm.org/ce/z/bFYnQW
smax-pos: https://alive2.llvm.org/ce/z/4xYSxR
smin-pos: https://alive2.llvm.org/ce/z/H3RPKj
umax : https://alive2.llvm.org/ce/z/P4oRcX
umin : https://alive2.llvm.org/ce/z/vWZG6p

Diff Detail

Event Timeline

goldstein.w.n created this revision.Feb 22 2023, 5:20 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 22 2023, 5:20 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
goldstein.w.n requested review of this revision.Feb 22 2023, 5:20 PM
Herald added a project: Restricted Project. · View Herald TranscriptFeb 22 2023, 5:20 PM
spatel added inline comments.Feb 23 2023, 8:45 AM
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
1498–1500

If we can prove that some value is a constant, then shouldn't we have zapped it already?
The test example shows that we are missing a fold like this:
https://alive2.llvm.org/ce/z/z5xok2

goldstein.w.n added inline comments.Feb 23 2023, 9:11 AM
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
1498–1500

If we can prove that some value is a constant, then shouldn't we have zapped it already?
The test example shows that we are missing a fold like this:
https://alive2.llvm.org/ce/z/z5xok2

It's one of the cases that falls through the cracks. IsPow2 && Negative implies int-min but we don't have an explicit check for that anywhere.

I considered adding it in computeKnownBits but it seems like an edge case that is not worth the significant amounts of extra analysis needed to cover it.
(similiar to how isKnownPowerOf2(X, /*OrZero*/false) misses alot of cases that could be covered if we just did isKnownPowerOf2(X, /*OrZero*/true) && isKnownNonZero(X) and isKnownNonZero(X) misses some cases that computeKnownBits(X) hits)

ValueTracking imo is a bit of a mess at the moment, but most of the easy fixes have compile time concerns.

spatel accepted this revision.Feb 23 2023, 11:35 AM

LGTM

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
1498

Its -> It's

1498–1500

Yes, it's messy, and it's not clear what is worth generalizing vs. pattern matching directly.

I filed https://github.com/llvm/llvm-project/issues/60957 - if you're seeing BMI-related patterns like this in real code, then it's probably worth getting that one way or another.

This revision is now accepted and ready to land.Feb 23 2023, 11:35 AM
goldstein.w.n marked an inline comment as done.Feb 23 2023, 11:46 AM
goldstein.w.n added inline comments.
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
1498–1500

Yes, it's messy, and it's not clear what is worth generalizing vs. pattern matching directly.

I filed https://github.com/llvm/llvm-project/issues/60957 - if you're seeing BMI-related patterns like this in real code, then it's probably worth getting that one way or another.

This revision was landed with ongoing or failed builds.Feb 24 2023, 1:22 PM
This revision was automatically updated to reflect the committed changes.