<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Oct 26, 2020 at 9:50 PM Philip Reames <<a href="mailto:listmail@philipreames.com">listmail@philipreames.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Are you going to handle other variants?  A few of potentials...<br></blockquote><div><br></div><div>Hi Philip -</div><div>This patch is a response to the discussion in <a href="https://reviews.llvm.org/D89952">https://reviews.llvm.org/D89952</a> ; see also <a href="https://reviews.llvm.org/D89976">https://reviews.llvm.org/D89976</a> and related commits.<br></div><div></div><div>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.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
ctpop(X) != 0 ==> X != 0.<br></blockquote><div><br></div><div>We have this in InstCombinerImpl::foldICmpEqIntrinsicWithConstant(). The code organization could probably be improved to make that clearer/more efficient...<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
ctpop(X) == C ==> X != C2 where all but one bit in X is known<br>
<br>
ctpop(X) > C ==> X & (C2) != 0 where C bits of X are known one and C2 is <br>
the inverse known zero mask.<br></blockquote><div><br></div><div>Do you have an example / benchmark that would benefit (best to file in bugzilla, so we can track it)?<br></div><div><br></div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Philip<br>
<br>
On 10/26/20 1:49 PM, Sanjay Patel via llvm-commits wrote:<br>
> Author: Sanjay Patel<br>
> Date: 2020-10-26T16:48:56-04:00<br>
> New Revision: 5a6e66ec72382d370046e04c415f8c3cb7e8b68d<br>
><br>
> URL: <a href="https://github.com/llvm/llvm-project/commit/5a6e66ec72382d370046e04c415f8c3cb7e8b68d" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/5a6e66ec72382d370046e04c415f8c3cb7e8b68d</a><br>
> DIFF: <a href="https://github.com/llvm/llvm-project/commit/5a6e66ec72382d370046e04c415f8c3cb7e8b68d.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/5a6e66ec72382d370046e04c415f8c3cb7e8b68d.diff</a><br>
><br>
> LOG: [InstCombine] add folds for icmp+ctpop<br>
><br>
> <a href="https://alive2.llvm.org/ce/z/XjFPQJ" rel="noreferrer" target="_blank">https://alive2.llvm.org/ce/z/XjFPQJ</a><br>
><br>
>    define void @src(i64 %value) {<br>
>      %t0 = call i64 @llvm.ctpop.i64(i64 %value)<br>
>      %gt = icmp ugt i64 %t0, 63<br>
>      %lt = icmp ult i64 %t0, 64<br>
>      call void @use(i1 %gt, i1 %lt)<br>
>      ret void<br>
>    }<br>
><br>
>    define void @tgt(i64 %value) {<br>
>      %eq = icmp eq i64 %value, -1<br>
>      %ne = icmp ne i64 %value, -1<br>
>      call void @use(i1 %eq, i1 %ne)<br>
>      ret void<br>
>    }<br>
><br>
>    declare i64 @llvm.ctpop.i64(i64) #1<br>
>    declare void @use(i1, i1)<br>
><br>
> Added:<br>
>      <br>
><br>
> Modified:<br>
>      llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp<br>
>      llvm/test/Transforms/InstCombine/cmp-intrinsic.ll<br>
><br>
> Removed:<br>
>      <br>
><br>
><br>
> ################################################################################<br>
> diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp<br>
> index 24713d7681b2..fe342dc2fc6c 100644<br>
> --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp<br>
> +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp<br>
> @@ -3174,6 +3174,18 @@ Instruction *InstCombinerImpl::foldICmpIntrinsicWithConstant(ICmpInst &Cmp,<br>
>     unsigned BitWidth = C.getBitWidth();<br>
>     ICmpInst::Predicate Pred = Cmp.getPredicate();<br>
>     switch (II->getIntrinsicID()) {<br>
> +  case Intrinsic::ctpop: {<br>
> +    // (ctpop X > BitWidth - 1) --> X == -1<br>
> +    Value *X = II->getArgOperand(0);<br>
> +    if (C == BitWidth - 1 && Pred == ICmpInst::ICMP_UGT)<br>
> +      return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_EQ, X,<br>
> +                             ConstantInt::getAllOnesValue(Ty));<br>
> +    // (ctpop X < BitWidth) --> X != -1<br>
> +    if (C == BitWidth && Pred == ICmpInst::ICMP_ULT)<br>
> +      return CmpInst::Create(Instruction::ICmp, ICmpInst::ICMP_NE, X,<br>
> +                             ConstantInt::getAllOnesValue(Ty));<br>
> +    break;<br>
> +  }<br>
>     case Intrinsic::ctlz: {<br>
>       // ctlz(0bXXXXXXXX) > 3 -> 0bXXXXXXXX < 0b00010000<br>
>       if (Pred == ICmpInst::ICMP_UGT && C.ult(BitWidth)) {<br>
><br>
> diff  --git a/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll b/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll<br>
> index 6519eda41499..599a749954d2 100644<br>
> --- a/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll<br>
> +++ b/llvm/test/Transforms/InstCombine/cmp-intrinsic.ll<br>
> @@ -495,7 +495,7 @@ define i1 @ctpop_ugt_bitwidth_minus_one_i8(i8 %x, i8* %p) {<br>
>   ; CHECK-LABEL: @ctpop_ugt_bitwidth_minus_one_i8(<br>
>   ; CHECK-NEXT:    [[POP:%.*]] = tail call i8 @llvm.ctpop.i8(i8 [[X:%.*]]), [[RNG2:!range !.*]]<br>
>   ; CHECK-NEXT:    store i8 [[POP]], i8* [[P:%.*]], align 1<br>
> -; CHECK-NEXT:    [[CMP:%.*]] = icmp ugt i8 [[POP]], 7<br>
> +; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[X]], -1<br>
>   ; CHECK-NEXT:    ret i1 [[CMP]]<br>
>   ;<br>
>     %pop = tail call i8 @llvm.ctpop.i8(i8 %x)<br>
> @@ -506,8 +506,7 @@ define i1 @ctpop_ugt_bitwidth_minus_one_i8(i8 %x, i8* %p) {<br>
>   <br>
>   define <2 x i1> @ctpop_ult_bitwidth_v2i32(<2 x i32> %x) {<br>
>   ; CHECK-LABEL: @ctpop_ult_bitwidth_v2i32(<br>
> -; CHECK-NEXT:    [[POP:%.*]] = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])<br>
> -; CHECK-NEXT:    [[CMP:%.*]] = icmp ult <2 x i32> [[POP]], <i32 32, i32 32><br>
> +; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i32> [[X:%.*]], <i32 -1, i32 -1><br>
>   ; CHECK-NEXT:    ret <2 x i1> [[CMP]]<br>
>   ;<br>
>     %pop = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %x)<br>
><br>
><br>
>          <br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>