Fold (-a >> b) and/or/xor (~a >> b) into (-a and/or/xor ~a) >> b https://github.com/llvm/llvm-project/issues/64304.
This optimization was already performed for unsigned arguments https://godbolt.org/z/xvvnxc4Ys, but for signed integers optimization could not be performed because of ashr (xor %x, -1), %y --> xor (ashr %x, %y), -1 transform that was introduced in https://github.com/llvm/llvm-project/commit/485c4b552b71aff21fc27ce958c2d8ea4cebba99#diff-8c60c0e9a2dee740856faa4e8c8e5545e3236565d003f85fec4650841c976268.
Alive proofs https://alive2.llvm.org/ce/z/HU-MJn, https://alive2.llvm.org/ce/z/pcXVgU, https://alive2.llvm.org/ce/z/RVqr_P.
Depends on D157289.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
Can we generalize foldBinOpShiftWithShift() to handle this? Or alternatively, can be fold foldBinOpShiftWithShift() into the special factorization case you're adding here? I'm not willing to have both. We also shouldn't be creating temporary instructions.
As far as I can tell the sub 0, x is irrelevant for the transform. Can you please remove it from the proofs (and tests)?
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | ||
---|---|---|
757 | There's just one kind of arithmetic shift, so it can't not match. | |
854 | Maybe match(Mask, m_AllOnes()) and leave CMask alone? This will also match splat vectors with undef values, so we'd need a test for that. | |
856 | Might as well CreateNot? | |
858 | Cast shouldn't be needed. |
Yes, sub 0, x is irrelevant for the transform. I need to use some instruction to transform x so that whole expression will not be optimized by other transformations. I updated tests to use mul, it seems from other tests mul and div are usually used for this.
Can't you just make it a separate argument? Like this: https://alive2.llvm.org/ce/z/ptdCGU
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | ||
---|---|---|
788 | Can you add assert ShOpc != Instruction::AShr here. Your code is fine in that regard, but now that the match logic supports AShr but much of the existing logic doesn't think we should have a fail-loudly check incase someone updates in the future. |
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp | ||
---|---|---|
783 | Also assert in here. |
There's just one kind of arithmetic shift, so it can't not match.