[llvm] [InstCombine] Fold redundant select guards for ctpop (PR #195443)

Sai Sanjay Chikne via llvm-commits llvm-commits at lists.llvm.org
Sat May 2 06:55:46 PDT 2026


================
@@ -4317,6 +4317,26 @@ Instruction *InstCombinerImpl::visitSelectInst(SelectInst &SI) {
   if (Instruction *I = canonicalizeScalarSelectOfVecs(SI, *this))
     return I;
 
+  // Fold: select (icmp ult X, 2), X, ctpop(X)  -->  ctpop(X)
+  // Fold: select (icmp eq X, -1), BitWidth, ctpop(X)  -->  ctpop(X)
+  // ctpop(0)==0, ctpop(1)==1, ctpop(-1)==BitWidth, so guards are redundant.
+  {
+    Value *X;
+    CmpPredicate CtpopPred;
+    Value *CtpopCmpLHS, *CtpopCmpRHS;
+    unsigned CtpopBitWidth = SelType->getScalarSizeInBits();
+    if (match(FalseVal, m_Intrinsic<Intrinsic::ctpop>(m_Value(X))) &&
+        match(CondVal, m_ICmp(CtpopPred, m_Value(CtpopCmpLHS), m_Value(CtpopCmpRHS)))) {
+      if (CtpopCmpLHS == X && CtpopPred == ICmpInst::ICMP_ULT &&
+          match(CtpopCmpRHS, m_SpecificInt(2)) && TrueVal == X)
+        return replaceInstUsesWith(SI, FalseVal);
----------------
sai18022001 wrote:

Dropped the `icmp eq X, -1` fold, it's covered by `foldSelectValueEquivalence` and @cardigan1008's case shows it can be incorrect with a narrowed range annotation.

For `icmp ult X, 2`, added `dropPoisonGeneratingAnnotations` and re-queue on ctpop, following the ctlz pattern. Pushing now.

https://github.com/llvm/llvm-project/pull/195443


More information about the llvm-commits mailing list