This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Optimize compares with multiple selects as operands
ClosedPublic

Authored by tejas on May 11 2023, 5:45 AM.

Details

Summary

In case of a comparison with two select instructions having the same
condition, check whether one of the resulting branches can be simplified.
If so, just compare the other branch and select the appropriate result.
For example:

%tmp1 = select i1 %cmp, i32 %y, i32 %x
%tmp2 = select i1 %cmp, i32 %z, i32 %x
%cmp2 = icmp slt i32 %tmp2, %tmp1

The icmp will result false for the false value of selects and the result
will depend upon the comparison of true values of selects if %cmp is
true. Thus, transform this into:

%cmp = icmp slt i32 %y, %z
%sel = select i1 %cond, i1 %cmp, i1 false

Diff Detail

Event Timeline

tejas created this revision.May 11 2023, 5:45 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 11 2023, 5:45 AM
Herald added a subscriber: hiraditya. · View Herald Transcript
tejas requested review of this revision.May 11 2023, 5:45 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 11 2023, 5:45 AM
tejas updated this revision to Diff 521273.May 11 2023, 5:46 AM

Updated with clang-format.

tejas added a comment.May 11 2023, 5:55 AM

Hi @jdoerfert @fhahn, can you please review this case for simplifying cmp with selects? It basically folds to an appropriate result by checking both the possible values of selects.

nikic added a reviewer: nikic.May 18 2023, 1:44 AM
nikic added a subscriber: nikic.

I think it would be better to implement this more general transform in InstCombine: https://alive2.llvm.org/ce/z/aN8q7S In the case where the new comparison constant-folds it reduces to what you're implementing here.

I think it would be better to implement this more general transform in InstCombine: https://alive2.llvm.org/ce/z/aN8q7S In the case where the new comparison constant-folds it reduces to what you're implementing here.

+1

tejas updated this revision to Diff 525124.May 24 2023, 5:34 AM
tejas retitled this revision from [InstSimplify] Optimize compares with multiple selects as operands to [InstCombine] Optimize compares with multiple selects as operands.
tejas edited the summary of this revision. (Show Details)

Made the transformation generic as suggested and moved it to InstCombine.

tejas added a comment.May 24 2023, 5:36 AM

Hi @nikic @goldstein.w.n , I have updated the patch just as suggested and moved it to InstCombine. Please review!
Thanks!

nikic requested changes to this revision.May 24 2023, 6:56 AM

Looks pretty reasonable.

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
6596–6597
6600

Setting the insertion point is unnecessary.

llvm/test/Transforms/InstCombine/icmp-with-selects.ll
4

Drop the noundef and zeroext parameters.

77

Add negative tests:

  1. Select conditions are not the same.
  2. Neither side simplifies.

Also add multi-use tests, where one/both selects have additional uses. You'll find that you need to add some one-use checks.

This revision now requires changes to proceed.May 24 2023, 6:56 AM
tejas updated this revision to Diff 525474.May 25 2023, 12:42 AM

Made specific changes to the code and removed insertion points. Added negative testcases.

tejas marked 4 inline comments as done.May 25 2023, 12:46 AM
tejas added inline comments.
llvm/test/Transforms/InstCombine/icmp-with-selects.ll
77

Added the negative tests. I had not added one-use checks since we are not explicitly removing the selects nor modifying them, but they do bloat up the code, so added now.

nikic added inline comments.May 25 2023, 12:58 AM
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
6597

There are two ways the one-use checks could be relaxed:

  1. It should be fine to only require one-use on one of the selects, as we'll preserve the number of instructions in that case. I'm not entirely clear on profitability for that case -- I guess the fact that we're converting an arbitrary select into a logical and/or may make it generally beneficial?
  2. If both comparisons fold, we don't care about uses at all, as the result is a constant.

I personally think it would be okay to start with the code you have, but in that case we should at least add a TODO to note the possibility.

llvm/test/Transforms/InstCombine/icmp-with-selects.ll
4

Could you please give these tests some more meaningful names, for example this could be something like @both_sides_fold.

126

For multi-use, it's customary to just do a call void @use(i32 %cond1). This is more obvious than trying to come up with a way to combine the uses.

tejas marked an inline comment as done.May 25 2023, 1:31 AM
tejas added inline comments.
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
6597

Can we go with relaxing the condition for one-use on one of the selects? if at least it seems beneficial at this point?

nikic added inline comments.May 25 2023, 1:32 AM
llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
6597

Sure!

tejas updated this revision to Diff 525523.May 25 2023, 3:23 AM

Relaxed the condition for one-use selects and refined the tests.

tejas marked 3 inline comments as done.May 25 2023, 3:24 AM
nikic added a comment.May 25 2023, 6:52 AM

Thanks, the implementation looks good to me. It would be good to also add some vector tests. In particular, we should have a test where the select result is a vector, and a test where both the select condition and select result is a vector. I think your code should already correctly handle these cases.

tejas updated this revision to Diff 525964.May 26 2023, 12:08 AM

Added the vector tests.

nikic accepted this revision.May 26 2023, 12:35 AM

LGTM. Assuming you don't have commit access, which Name <email> should I use when landing?

The tests will have to be precommitted (see https://llvm.org/docs/TestingGuide.html#precommit-workflow-for-tests), but I can do that while landing.

This revision is now accepted and ready to land.May 26 2023, 12:35 AM
tejas added a comment.May 26 2023, 3:20 AM

Thanks for your comments and submitting the patch on my behalf! Please use Tejas Joshi <TejasSanjay.Joshi@amd.com> for landing.

This revision was landed with ongoing or failed builds.May 26 2023, 7:05 AM
This revision was automatically updated to reflect the committed changes.