This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] Handle integer extension in `select` patterns using the condition as value
ClosedPublic

Authored by zero9178 on Sep 18 2022, 12:03 PM.

Details

Summary

These patterns were previously only implemented for i1 type but can be extended for any integer type by also handling zext and sext operands.

Diff Detail

Event Timeline

zero9178 created this revision.Sep 18 2022, 12:03 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 18 2022, 12:03 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
zero9178 requested review of this revision.Sep 18 2022, 12:03 PM
Herald added a project: Restricted Project. · View Herald TranscriptSep 18 2022, 12:03 PM
RKSimon added inline comments.Sep 18 2022, 1:28 PM
llvm/test/Transforms/InstSimplify/select.ll
1121 ↗(On Diff #461090)

please can you add vector test coverage? and possibly a negative test for the case where the true/false args are commuted?

zero9178 updated this revision to Diff 461096.Sep 18 2022, 1:36 PM

Address review comments: Add test using vector types and a negative test with switched true false operands

This match seems over-specified. If either the true or false arm of the select are cast from the select condition, then we can replace that arm in -instcombine, and it should collapse to zero when both arms match:
https://alive2.llvm.org/ce/z/35kadA

zero9178 updated this revision to Diff 461536.Sep 20 2022, 5:02 AM
zero9178 retitled this revision from [InstSimplify] Fold `select C, not(C), C` to zero to [InstCombine] Handle integer extension in `select` patterns using the condition as value.
zero9178 edited the summary of this revision. (Show Details)

Address review comments: Change approach to handling it in InstCombine. I noticed that these "implication" patterns for the condition being used as either the true or false values already existed but have simply only been handled for i1 selection type while not taking zext and sext into account.
I now made these also handle zext and sext as well, making it capable of handling any integer type.

Address review comments: Change approach to handling it in InstCombine. I noticed that these "implication" patterns for the condition being used as either the true or false values already existed but have simply only been handled for i1 selection type while not taking zext and sext into account.
I now made these also handle zext and sext as well, making it capable of handling any integer type.

Nice improvement! Do you want to add a couple of tests to model your motivating example (where both arms of the select are extended)? Please pre-commit the tests with baseline output, then update the patch here, so it shows test diffs.

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
2671–2672

Nit: I'd make all of these ConstantInt::get***() for consistency since we know all of them are integer types.

2683–2685

Change the "false" to "0" to be more general in these comments (and similar for "true" -> "1" below).

nikic added a subscriber: nikic.Sep 20 2022, 6:02 AM

This kinda looks like foldSelectValueEquivalence() with a trivial comparison (i.e. interpret c as c == 1).

zero9178 updated this revision to Diff 461553.Sep 20 2022, 6:13 AM

Address review comments:

  • Consistently use ConstantInt
  • Use 0 and 1 instead of true and false in comments, since it is now applicable to all integer types, not just i1
  • Add test coverage for original motivating example. I only added the zext/sext and sext/zext cases, as the other cases are comparatively uniniteresting and were previously already handled by sinking of the casts below the select
  • Precommit tests and rebase this patch on top of it
zero9178 marked 2 inline comments as done.Sep 20 2022, 6:16 AM

This kinda looks like foldSelectValueEquivalence() with a trivial comparison (i.e. interpret c as c == 1).

Agree - but we'd have to account for the missing icmp that code is expecting? Not sure that's worth the effort and reduced readability, so this patch LGTM.

nikic added a comment.Sep 20 2022, 9:19 AM

This kinda looks like foldSelectValueEquivalence() with a trivial comparison (i.e. interpret c as c == 1).

Agree - but we'd have to account for the missing icmp that code is expecting? Not sure that's worth the effort and reduced readability, so this patch LGTM.

It looks like we don't even need foldSelectValueEquivalence here -- we already have simplifyWithOpReplaced() folds for these. They are currently behind a guard for i1 selects, but if we move them outside we get most of the mileage: https://gist.github.com/nikic/86420628e72dd137aa56d2317f3825b0

The main caveat is that this does not handle vectors. Not that I actually care about vectors, but for the sake of propriety we should probably update simplifyWithOpReplaced() to allow vectors and only reject the problematic cross-lane operations inside.

This kinda looks like foldSelectValueEquivalence() with a trivial comparison (i.e. interpret c as c == 1).

Agree - but we'd have to account for the missing icmp that code is expecting? Not sure that's worth the effort and reduced readability, so this patch LGTM.

It looks like we don't even need foldSelectValueEquivalence here -- we already have simplifyWithOpReplaced() folds for these. They are currently behind a guard for i1 selects, but if we move them outside we get most of the mileage: https://gist.github.com/nikic/86420628e72dd137aa56d2317f3825b0

The main caveat is that this does not handle vectors. Not that I actually care about vectors, but for the sake of propriety we should probably update simplifyWithOpReplaced() to allow vectors and only reject the problematic cross-lane operations inside.

That also misses the basic patterns with a 'not' before the extend. I like the smaller patch, but given that this one covers more cases, I'd still go with this patch as-is.

nikic accepted this revision.Sep 20 2022, 11:03 AM

Okay, let's go with this for now. I can come back later and refactor this to use generic folds when I have time.

This revision is now accepted and ready to land.Sep 20 2022, 11:03 AM
This revision was landed with ongoing or failed builds.Sep 20 2022, 1:25 PM
This revision was automatically updated to reflect the committed changes.