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
This commit is contained in:
Amaury Sechet 2016-08-04 05:27:20 +00:00
parent 4eefd6bca4
commit 6bea674c43
2 changed files with 32 additions and 16 deletions

View File

@ -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;

View File

@ -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 {