diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -6460,6 +6460,11 @@ unsigned Width = Lower.getBitWidth(); const APInt *C; switch (II.getIntrinsicID()) { + case Intrinsic::ctpop: + // Maximum of set bits is the bit width. + assert(Lower == 0 && "Expected lower bound to be zero"); + Upper = Width + 1; + break; case Intrinsic::uadd_sat: // uadd.sat(x, C) produces [C, UINT_MAX]. if (match(II.getOperand(0), m_APInt(C)) || diff --git a/llvm/test/Transforms/InstSimplify/compare.ll b/llvm/test/Transforms/InstSimplify/compare.ll --- a/llvm/test/Transforms/InstSimplify/compare.ll +++ b/llvm/test/Transforms/InstSimplify/compare.ll @@ -2073,9 +2073,7 @@ define i1 @ctpop_sgt_bitwidth(i11 %x) { ; CHECK-LABEL: @ctpop_sgt_bitwidth( -; CHECK-NEXT: [[POP:%.*]] = call i11 @llvm.ctpop.i11(i11 [[X:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i11 [[POP]], 11 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %pop = call i11 @llvm.ctpop.i11(i11 %x) %cmp = icmp sgt i11 %pop, 11 @@ -2084,9 +2082,7 @@ define i1 @ctpop_sle_minus1(i11 %x) { ; CHECK-LABEL: @ctpop_sle_minus1( -; CHECK-NEXT: [[POP:%.*]] = call i11 @llvm.ctpop.i11(i11 [[X:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = icmp sle i11 [[POP]], -1 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %pop = call i11 @llvm.ctpop.i11(i11 %x) %cmp = icmp sle i11 %pop, -1 @@ -2095,15 +2091,15 @@ define i1 @ctpop_ugt_bitwidth(i73 %x) { ; CHECK-LABEL: @ctpop_ugt_bitwidth( -; CHECK-NEXT: [[POP:%.*]] = call i73 @llvm.ctpop.i73(i73 [[X:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i73 [[POP]], 73 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %pop = call i73 @llvm.ctpop.i73(i73 %x) %cmp = icmp ugt i73 %pop, 73 ret i1 %cmp } +; Negative test - does not simplify, but instcombine could reduce this. + define i1 @ctpop_ugt_bitwidth_minus1(i73 %x) { ; CHECK-LABEL: @ctpop_ugt_bitwidth_minus1( ; CHECK-NEXT: [[POP:%.*]] = call i73 @llvm.ctpop.i73(i73 [[X:%.*]]) @@ -2117,9 +2113,7 @@ define <2 x i1> @ctpop_sgt_bitwidth_splat(<2 x i13> %x) { ; CHECK-LABEL: @ctpop_sgt_bitwidth_splat( -; CHECK-NEXT: [[POP:%.*]] = call <2 x i13> @llvm.ctpop.v2i13(<2 x i13> [[X:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i13> [[POP]], -; CHECK-NEXT: ret <2 x i1> [[CMP]] +; CHECK-NEXT: ret <2 x i1> zeroinitializer ; %pop = call <2 x i13> @llvm.ctpop.v2i13(<2 x i13> %x) %cmp = icmp sgt <2 x i13> %pop, @@ -2128,9 +2122,7 @@ define i1 @ctpop_ult_plus1_bitwidth(i11 %x) { ; CHECK-LABEL: @ctpop_ult_plus1_bitwidth( -; CHECK-NEXT: [[POP:%.*]] = call i11 @llvm.ctpop.i11(i11 [[X:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i11 [[POP]], 12 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %pop = call i11 @llvm.ctpop.i11(i11 %x) %cmp = icmp ult i11 %pop, 12 @@ -2139,9 +2131,7 @@ define i1 @ctpop_ne_big_bitwidth(i73 %x) { ; CHECK-LABEL: @ctpop_ne_big_bitwidth( -; CHECK-NEXT: [[POP:%.*]] = call i73 @llvm.ctpop.i73(i73 [[X:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i73 [[POP]], 75 -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 true ; %pop = call i73 @llvm.ctpop.i73(i73 %x) %cmp = icmp ne i73 %pop, 75 @@ -2150,15 +2140,15 @@ define <2 x i1> @ctpop_slt_bitwidth_plus1_splat(<2 x i13> %x) { ; CHECK-LABEL: @ctpop_slt_bitwidth_plus1_splat( -; CHECK-NEXT: [[POP:%.*]] = call <2 x i13> @llvm.ctpop.v2i13(<2 x i13> [[X:%.*]]) -; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i13> [[POP]], -; CHECK-NEXT: ret <2 x i1> [[CMP]] +; CHECK-NEXT: ret <2 x i1> ; %pop = call <2 x i13> @llvm.ctpop.v2i13(<2 x i13> %x) %cmp = icmp slt <2 x i13> %pop, ret <2 x i1> %cmp } +; Negative test - does not simplify, but instcombine could reduce this. + define <2 x i1> @ctpop_slt_bitwidth_splat(<2 x i13> %x) { ; CHECK-LABEL: @ctpop_slt_bitwidth_splat( ; CHECK-NEXT: [[POP:%.*]] = call <2 x i13> @llvm.ctpop.v2i13(<2 x i13> [[X:%.*]])