This is an archive of the discontinued LLVM Phabricator instance.

[InstCombine] add casts from splat-a-bit pattern if necessary
ClosedPublic

Authored by Chenbing.Zheng on Apr 27 2022, 6:51 PM.

Details

Summary

Splatting a bit of constant-index across a value:
sext (ashr (trunc iN X to iM), M-1) to iN --> ashr (shl X, N-M), N-1
If the dest type is different, use a cast (adjust use check).

https://alive2.llvm.org/ce/z/acAan3

Diff Detail

Event Timeline

Chenbing.Zheng created this revision.Apr 27 2022, 6:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 27 2022, 6:51 PM
Herald added a subscriber: hiraditya. · View Herald Transcript
Chenbing.Zheng requested review of this revision.Apr 27 2022, 6:51 PM
spatel added inline comments.Apr 28 2022, 11:31 AM
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
1595

The TODO says we need to adjust (add) a use check, but this patch did not do that.

Please add a test like this to check that we have the correct behavior:

declare void @use(i8)
define i16 @smear_set_bit_different_dest_type_extra_use(i32 %x) {
  %t = trunc i32 %x to i8
  call void @use(i8 %t)
  %a = ashr i8 %t, 7
  %s = sext i8 %a to i16
  ret i16 %s
}
1612–1614

These 3 values are common in both cases - I think it's better to not repeat the code on both sides of the if/else.

1616

We need another test to verify what happens when DestTy is wider than XTy.

Chenbing.Zheng added inline comments.Apr 28 2022, 7:22 PM
llvm/test/Transforms/InstCombine/sext.ll
397

For this case, we get a correct result, but it is longer. Should I limit trunc one-use to break it?

spatel added inline comments.Apr 29 2022, 5:59 AM
llvm/test/Transforms/InstCombine/sext.ll
397

Yes - we do not want to create more instructions than we started with. That is the purpose for the code comment ("adjust use check)".

adjust use check

Chenbing.Zheng marked 4 inline comments as done.May 4 2022, 11:58 PM

Please can you pre-commit the new tests and rebase the patch to show the codegen diff

spatel added inline comments.May 5 2022, 8:43 AM
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
1611–1612

There's a potential subtle difference with constant expressions, but you could reduce this to:

if (cast<BinaryOperator>(Src)->getOperand(0)->hasOneUse()) {

The m_Ashr guarantees that we matched a binary operator, so it's ok to plain "cast" it to that type. You could also capture the trunc in the first match with something like this:

Instruction *Trunc;
if (match(Src, m_OneUse(m_AShr(
                   m_CombineAnd(m_Trunc(m_Value(X)), m_Instruction(Trunc)),
                   m_SpecificInt(SrcBitSize - 1))))) {

Then the use check is the straightforward:

if (Trunc->hasOneUse()) {
llvm/test/Transforms/InstCombine/sext.ll
413

Please pre-commit the baseline tests and update here, so we just show the diffs.

address comments

Chenbing.Zheng added inline comments.May 5 2022, 8:10 PM
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
1611–1612

Done and thank you for your detailed explanation.

spatel accepted this revision.May 6 2022, 4:53 AM

LGTM

This revision is now accepted and ready to land.May 6 2022, 4:53 AM
This revision was landed with ongoing or failed builds.May 7 2022, 12:37 AM
This revision was automatically updated to reflect the committed changes.