This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Fold (-a >> b) and/or/xor (~a >> b) into (-a and/or/xor ~a) >> b
ClosedPublic

Authored by kitaisreal on Aug 7 2023, 8:26 AM.

Details

Summary

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.

Diff Detail

Event Timeline

kitaisreal created this revision.Aug 7 2023, 8:26 AM
kitaisreal requested review of this revision.Aug 7 2023, 8:26 AM
goldstein.w.n added inline comments.Aug 7 2023, 11:03 AM
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
1008

Imo the LHS/RHS logic are similiar enough it should be a lambda. Will make the code a lot cleaner.

1022

This codeblock needs some comments.

nikic requested changes to this revision.Aug 8 2023, 12:57 PM

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.

This revision now requires changes to proceed.Aug 8 2023, 12:57 PM
kitaisreal retitled this revision from [InstCombine] Fold (-a >> b) and/or (~a >> b) into (-a and/or ~a) >> b to [InstCombine] Fold (-a >> b) and/or/xor (~a >> b) into (-a and/or/xor ~a) >> b.
kitaisreal edited the summary of this revision. (Show Details)

Updated implementation.

kitaisreal marked 2 inline comments as done.Aug 12 2023, 8:07 AM

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.

Moved implementation to foldBinOpShiftWithShift().

nikic added a comment.Aug 12 2023, 8:45 AM

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.

kitaisreal marked 4 inline comments as done.

Updated implementation.

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)?

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.

nikic added a comment.Aug 12 2023, 1:24 PM

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)?

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

Updated implementation.

kitaisreal edited the summary of this revision. (Show Details)Aug 13 2023, 8:40 AM

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)?

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

Sure, updated implementation, tests and proofs.

goldstein.w.n added inline comments.Aug 13 2023, 8:48 AM
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.

goldstein.w.n added inline comments.Aug 13 2023, 8:49 AM
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
783

Also assert in here.

nikic accepted this revision.Aug 14 2023, 3:05 AM

LGTM apart from @goldstein.w.n's nits.

This revision is now accepted and ready to land.Aug 14 2023, 3:05 AM
kitaisreal marked 2 inline comments as done.

Added asserts.

Updated tests.

@nikic can you accept this revision again after I changed tests ?