[InstCombine] convert mask and shift of power-of-2 to cmp+select
authorSanjay Patel <spatel@rotateright.com>
Fri, 17 Jun 2022 14:41:00 +0000 (10:41 -0400)
committerSanjay Patel <spatel@rotateright.com>
Fri, 17 Jun 2022 14:51:57 +0000 (10:51 -0400)
commitbfde8619355a06d9f1a199e9cb3f8d41aef5c05b
tree6364dba516b8741ba69ad5473c092bfbfb78176a
parent1a02c963e338100a3000734b91f5956da9b8c95e
[InstCombine] convert mask and shift of power-of-2 to cmp+select

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 can partially invert this
in both cases if that is profitable. It is not trivially reversible,
however, so if we find perf regressions that are not easy to undo,
then we may want to revert this.

Differential Revision: https://reviews.llvm.org/D127801
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/test/Transforms/InstCombine/and.ll
llvm/test/Transforms/InstCombine/icmp-and-shift.ll
llvm/test/Transforms/InstCombine/lshr-and-signbit-icmpeq-zero.ll