summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmaury Sechet <deadalnix@gmail.com>2016-08-04 05:27:20 +0000
committerAmaury Sechet <deadalnix@gmail.com>2016-08-04 05:27:20 +0000
commit6bea674c43e9a7c4078578e496887c1f07bba886 (patch)
treed12199789502654907c6308042167a83eff78f9f
parent4eefd6bca47121cfd5f0a6b3d78576a0c0404afa (diff)
downloadbcm5719-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.cpp14
-rw-r--r--llvm/test/Transforms/InstCombine/intrinsics.ll34
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 {
OpenPOWER on IntegriCloud