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 @@ -4794,6 +4794,14 @@ // destination type. return true; case Instruction::Call: + if (auto *II = dyn_cast(Op)) { + switch (II->getIntrinsicID()) { + // TODO: Add more intrinsics. + case Intrinsic::ctpop: + return false; + } + } + LLVM_FALLTHROUGH; case Instruction::CallBr: case Instruction::Invoke: { const auto *CB = cast(Op); diff --git a/llvm/test/Transforms/InstSimplify/select.ll b/llvm/test/Transforms/InstSimplify/select.ll --- a/llvm/test/Transforms/InstSimplify/select.ll +++ b/llvm/test/Transforms/InstSimplify/select.ll @@ -1015,6 +1015,20 @@ ret i32 %sel } +define i32 @select_ctpop_zero(i32 %x) { +; CHECK-LABEL: @select_ctpop_zero( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctpop.i32(i32 [[X:%.*]]) +; CHECK-NEXT: ret i32 [[TMP0]] +; +entry: + %0 = icmp eq i32 %x, 0 + %1 = call i32 @llvm.ctpop.i32(i32 %x) + %sel = select i1 %0, i32 0, i32 %1 + ret i32 %sel +} +declare i32 @llvm.ctpop.i32(i32) + ; TODO: these can be optimized more define i32 @poison(i32 %x, i32 %y) {