[llvm] 5a6e66e - [InstCombine] add folds for icmp+ctpop

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 27 05:55:36 PDT 2020


On Mon, Oct 26, 2020 at 9:50 PM Philip Reames <listmail at philipreames.com>
wrote:

> Are you going to handle other variants?  A few of potentials...
>

Hi Philip -
This patch is a response to the discussion in
https://reviews.llvm.org/D89952 ; see also https://reviews.llvm.org/D89976
and related commits.
I was closing some IR optimizer gaps to hopefully make life easier for
codegen. I don't personally have the motivating cases to do more work here
currently.


> ctpop(X) != 0 ==> X != 0.
>

We have this in InstCombinerImpl::foldICmpEqIntrinsicWithConstant(). The
code organization could probably be improved to make that clearer/more
efficient...


> ctpop(X) == C ==> X != C2 where all but one bit in X is known
>
> ctpop(X) > C ==> X & (C2) != 0 where C bits of X are known one and C2 is
> the inverse known zero mask.
>

Do you have an example / benchmark that would benefit (best to file in
bugzilla, so we can track it)?





> Philip
>
> On 10/26/20 1:49 PM, Sanjay Patel via llvm-commits wrote:
> > Author: Sanjay Patel
> > Date: 2020-10-26T16:48:56-04:00
> > New Revision: 5a6e66ec72382d370046e04c415f8c3cb7e8b68d
> >
> > URL:
> https://github.com/llvm/llvm-project/commit/5a6e66ec72382d370046e04c415f8c3cb7e8b68d
> > DIFF:
> https://github.com/llvm/llvm-project/commit/5a6e66ec72382d370046e04c415f8c3cb7e8b68d.diff
> >
> > LOG: [InstCombine] add folds for icmp+ctpop
> >
> > https://alive2.llvm.org/ce/z/XjFPQJ
> >
> >    define void @src(i64 %value) {
> >      %t0 = call i64 @llvm.ctpop.i64(i64 %value)
> >      %gt = icmp ugt i64 %t0, 63
> >      %lt = icmp ult i64 %t0, 64
> >      call void @use(i1 %gt, i1 %lt)
> >      ret void
> >    }
> >
> >    define void @tgt(i64 %value) {
> >      %eq = icmp eq i64 %value, -1
> >      %ne = icmp ne i64 %value, -1
> >      call void @use(i1 %eq, i1 %ne)
> >      ret void
> >    }
> >
> >    declare i64 @llvm.ctpop.i64(i64) #1
> >    declare void @use(i1, i1)
> >
> > Added:
> >
> >
> > Modified:
> >      llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
> >      llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
> >
> > Removed:
> >
> >
> >
> >
> ################################################################################
> > diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
> b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
> > index 24713d7681b2..fe342dc2fc6c 100644
> > --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
> > +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
> > @@ -3174,6 +3174,18 @@ Instruction
> *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,
> >     unsigned BitWidth = C.getBitWidth();
> >     ICmpInst::Predicate Pred = Cmp.getPredicate();
> >     switch (II->getIntrinsicID()) {
> > +  case Intrinsic::ctpop: {
> > +    // (ctpop X > BitWidth - 1) --> X == -1
> > +    Value *X = II->getArgOperand(0);
> > +    if (C == BitWidth - 1 && Pred == ICmpInst::ICMP_UGT)
> > +      return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, X,
> > +                             ConstantInt::getAllOnesValue(Ty));
> > +    // (ctpop X < BitWidth) --> X != -1
> > +    if (C == BitWidth && Pred == ICmpInst::ICMP_ULT)
> > +      return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, X,
> > +                             ConstantInt::getAllOnesValue(Ty));
> > +    break;
> > +  }
> >     case Intrinsic::ctlz: {
> >       // ctlz(0bXXXXXXXX) > 3 -> 0bXXXXXXXX < 0b00010000
> >       if (Pred == ICmpInst::ICMP_UGT && C.ult(BitWidth)) {
> >
> > diff  --git a/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
> b/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
> > index 6519eda41499..599a749954d2 100644
> > --- a/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
> > +++ b/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll
> > @@ -495,7 +495,7 @@ define i1 @ctpop_ugt_bitwidth_minus_one_i8(i8 %x,
> i8* %p) {
> >   ; CHECK-LABEL: @ctpop_ugt_bitwidth_minus_one_i8(
> >   ; CHECK-NEXT:    [[POP:%.*]] = tail call i8 @llvm.ctpop.i8(i8
> [[X:%.*]]), [[RNG2:!range !.*]]
> >   ; CHECK-NEXT:    store i8 [[POP]], i8* [[P:%.*]], align 1
> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[POP]], 7
> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], -1
> >   ; CHECK-NEXT:    ret i1 [[CMP]]
> >   ;
> >     %pop = tail call i8 @llvm.ctpop.i8(i8 %x)
> > @@ -506,8 +506,7 @@ define i1 @ctpop_ugt_bitwidth_minus_one_i8(i8 %x,
> i8* %p) {
> >
> >   define <2 x i1> @ctpop_ult_bitwidth_v2i32(<2 x i32> %x) {
> >   ; CHECK-LABEL: @ctpop_ult_bitwidth_v2i32(
> > -; CHECK-NEXT:    [[POP:%.*]] = tail call <2 x i32> @llvm.ctpop.v2i32(<2
> x i32> [[X:%.*]])
> > -; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[POP]], <i32 32, i32
> 32>
> > +; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 -1,
> i32 -1>
> >   ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
> >   ;
> >     %pop = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %x)
> >
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20201027/b91b5074/attachment.html>


More information about the llvm-commits mailing list