diff options
| author | Amaury Sechet <deadalnix@gmail.com> | 2016-08-04 05:27:20 +0000 |
|---|---|---|
| committer | Amaury Sechet <deadalnix@gmail.com> | 2016-08-04 05:27:20 +0000 |
| commit | 6bea674c43e9a7c4078578e496887c1f07bba886 (patch) | |
| tree | d12199789502654907c6308042167a83eff78f9f | |
| parent | 4eefd6bca47121cfd5f0a6b3d78576a0c0404afa (diff) | |
| download | bcm5719-llvm-6bea674c43e9a7c4078578e496887c1f07bba886.tar.gz bcm5719-llvm-6bea674c43e9a7c4078578e496887c1f07bba886.zip | |
Add popcount(n) == bitsize(n) -> n == -1 transformation.
Summary: As per title.
Reviewers: majnemer, spatel
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D23139
llvm-svn: 277694
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 14 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/intrinsics.ll | 34 |
2 files changed, 32 insertions, 16 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index 75c434265fb..6a798f91759 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2372,7 +2372,7 @@ Instruction *InstCombiner::foldICmpIntrinsicWithConstant(ICmpInst &ICI) { return &ICI; case Intrinsic::ctlz: case Intrinsic::cttz: - // ctz(A) == bitwidth(a) -> A == 0 and likewise for != + // ctz(A) == bitwidth(A) -> A == 0 and likewise for != if (*Op1C == Op1C->getBitWidth()) { Worklist.Add(II); ICI.setOperand(0, II->getArgOperand(0)); @@ -2380,14 +2380,20 @@ Instruction *InstCombiner::foldICmpIntrinsicWithConstant(ICmpInst &ICI) { return &ICI; } break; - case Intrinsic::ctpop: + case Intrinsic::ctpop: { // popcount(A) == 0 -> A == 0 and likewise for != - if (*Op1C == 0) { + // popcount(A) == bitwidth(A) -> A == -1 and likewise for != + bool IsZero = *Op1C == 0; + if (IsZero || *Op1C == Op1C->getBitWidth()) { Worklist.Add(II); ICI.setOperand(0, II->getArgOperand(0)); - ICI.setOperand(1, ConstantInt::getNullValue(II->getType())); + auto *NewOp = IsZero + ? ConstantInt::getNullValue(II->getType()) + : ConstantInt::getAllOnesValue(II->getType()); + ICI.setOperand(1, NewOp); return &ICI; } + } break; default: break; diff --git a/llvm/test/Transforms/InstCombine/intrinsics.ll b/llvm/test/Transforms/InstCombine/intrinsics.ll index f3845832c66..68f4687c7b3 100644 --- a/llvm/test/Transforms/InstCombine/intrinsics.ll +++ b/llvm/test/Transforms/InstCombine/intrinsics.ll @@ -302,9 +302,12 @@ entry: %tz = tail call i32 @llvm.cttz.i32(i32 %a, i1 false) nounwind readnone %tz.cmp = icmp ne i32 %tz, 32 store volatile i1 %tz.cmp, i1* %c - %pop = tail call i32 @llvm.ctpop.i32(i32 %b) nounwind readnone - %pop.cmp = icmp eq i32 %pop, 0 - store volatile i1 %pop.cmp, i1* %c + %pop0 = tail call i32 @llvm.ctpop.i32(i32 %b) nounwind readnone + %pop0.cmp = icmp eq i32 %pop0, 0 + store volatile i1 %pop0.cmp, i1* %c + %pop1 = tail call i32 @llvm.ctpop.i32(i32 %b) nounwind readnone + %pop1.cmp = icmp eq i32 %pop1, 32 + store volatile i1 %pop1.cmp, i1* %c ret void ; CHECK: @cmp.simplify ; CHECK-NEXT: entry: @@ -312,8 +315,10 @@ entry: ; CHECK-NEXT: store volatile i1 %lz.cmp, i1* %c ; CHECK-NEXT: %tz.cmp = icmp ne i32 %a, 0 ; CHECK-NEXT: store volatile i1 %tz.cmp, i1* %c -; CHECK-NEXT: %pop.cmp = icmp eq i32 %b, 0 -; CHECK-NEXT: store volatile i1 %pop.cmp, i1* %c +; CHECK-NEXT: %pop0.cmp = icmp eq i32 %b, 0 +; CHECK-NEXT: store volatile i1 %pop0.cmp, i1* %c +; CHECK-NEXT: %pop1.cmp = icmp eq i32 %b, -1 +; CHECK-NEXT: store volatile i1 %pop1.cmp, i1* %c } define <2 x i1> @ctlz_cmp_vec(<2 x i32> %a) { @@ -336,14 +341,19 @@ define <2 x i1> @cttz_cmp_vec(<2 x i32> %a) { ret <2 x i1> %cmp } -define <2 x i1> @ctpop_cmp_vec(<2 x i32> %a) { +define void @ctpop_cmp_vec(<2 x i32> %a, <2 x i1>* %b) { + %pop0 = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a) nounwind readnone + %pop0.cmp = icmp eq <2 x i32> %pop0, zeroinitializer + store volatile <2 x i1> %pop0.cmp, <2 x i1>* %b + %pop1 = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a) nounwind readnone + %pop1.cmp = icmp eq <2 x i32> %pop1, < i32 32, i32 32 > + store volatile <2 x i1> %pop1.cmp, <2 x i1>* %b + ret void ; CHECK-LABEL: @ctpop_cmp_vec( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i32> %a, zeroinitializer -; CHECK-NEXT: ret <2 x i1> [[CMP]] -; - %x = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %a) nounwind readnone - %cmp = icmp eq <2 x i32> %x, zeroinitializer - ret <2 x i1> %cmp +; CHECK-NEXT: %pop0.cmp = icmp eq <2 x i32> %a, zeroinitializer +; CHECK-NEXT: store volatile <2 x i1> %pop0.cmp, <2 x i1>* %c +; CHECK-NEXT: %pop1.cmp = icmp eq <2 x i32> %a, zeroinitializer +; CHECK-NEXT: store volatile <2 x i1> %pop1.cmp, <2 x i1>* %c } define i32 @cttz_simplify1a(i32 %x) nounwind readnone ssp { |

