optimize comparisons against cttz/ctlz/ctpop, patch by Alastair Lynn!


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@92745 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 90ab4f4..abbc89b 100644
--- a/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1418,11 +1418,33 @@
       }
     } else if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(LHSI)) {
       // Handle icmp {eq|ne} <intrinsic>, intcst.
-      if (II->getIntrinsicID() == Intrinsic::bswap) {
+      switch (II->getIntrinsicID()) {
+      case Intrinsic::bswap:
         Worklist.Add(II);
         ICI.setOperand(0, II->getOperand(1));
         ICI.setOperand(1, ConstantInt::get(II->getContext(), RHSV.byteSwap()));
         return &ICI;
+      case Intrinsic::ctlz:
+      case Intrinsic::cttz:
+        // ctz(A) == bitwidth(a)  ->  A == 0 and likewise for !=
+        if (RHSV == RHS->getType()->getBitWidth()) {
+          Worklist.Add(II);
+          ICI.setOperand(0, II->getOperand(1));
+          ICI.setOperand(1, ConstantInt::get(RHS->getType(), 0));
+          return &ICI;
+        }
+        break;
+      case Intrinsic::ctpop:
+        // popcount(A) == 0  ->  A == 0 and likewise for !=
+        if (RHS->isZero()) {
+          Worklist.Add(II);
+          ICI.setOperand(0, II->getOperand(1));
+          ICI.setOperand(1, RHS);
+          return &ICI;
+        }
+        break;
+      default:
+      	break;
       }
     }
   }