When the mask is a power-of-2 constant and op0 is a shifted-power-of-2 constant, test if the shift amount equals the offset bit index:
(ShiftC << X) & C --> X == (log2(C) - log2(ShiftC)) ? C : 0 (ShiftC >> X) & C --> X == (log2(ShiftC) - log2(C)) ? C : 0
This is an alternate to D127610 with a more general pattern. We match only shift+and instead of the trailing xor, so we see a few more tests diffs. I think we discussed this initially in D126617.
Here are proofs for shifts in both directions:
https://alive2.llvm.org/ce/z/CFrLs4
The test diffs look equal or better for IR, and this makes the patterns more uniform in IR. The backend would likely invert this in both cases if that is profitable, and there's already code in place to do that.
op0 -> Op0