InstCombine: Replace a hand-rolled version of isKnownToBeAPowerOfTwo with the real...
authorBenjamin Kramer <benny.kra@googlemail.com>
Sun, 19 Jan 2014 16:48:41 +0000 (16:48 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Sun, 19 Jan 2014 16:48:41 +0000 (16:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199604 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
test/Transforms/InstCombine/onehot_merge.ll

index 88bb69beef03ceb2c5003bd4d0b140c4f966eef1..c520db597c318b5c3675dcc58bb40942c79f96b4 100644 (file)
@@ -1543,23 +1543,6 @@ static Instruction *MatchSelectFromAndOr(Value *A, Value *B,
   return 0;
 }
 
-/// IsOneHotValue - Returns true for "one-hot" values (values where at most
-/// one bit can be set).
-static bool IsOneHotValue(Value *V) {
-  // Match 1<<K.
-  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(V))
-    if (BO->getOpcode() == Instruction::Shl) {
-      ConstantInt *One = dyn_cast<ConstantInt>(BO->getOperand(0));
-      return One && One->isOne();
-    }
-
-  // Check for power of two integer constants.
-  if (ConstantInt *K = dyn_cast<ConstantInt>(V))
-    return K->getValue().isPowerOf2();
-
-  return false;
-}
-
 /// FoldOrOfICmps - Fold (icmp)|(icmp) if possible.
 Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
   ICmpInst::Predicate LHSCC = LHS->getPredicate(), RHSCC = RHS->getPredicate();
@@ -1581,13 +1564,13 @@ Value *InstCombiner::FoldOrOfICmps(ICmpInst *LHS, ICmpInst *RHS) {
       Value *Mask = 0;
       Value *Masked = 0;
       if (LAnd->getOperand(0) == RAnd->getOperand(0) &&
-          IsOneHotValue(LAnd->getOperand(1)) &&
-          IsOneHotValue(RAnd->getOperand(1))) {
+          isKnownToBeAPowerOfTwo(LAnd->getOperand(1)) &&
+          isKnownToBeAPowerOfTwo(RAnd->getOperand(1))) {
         Mask = Builder->CreateOr(LAnd->getOperand(1), RAnd->getOperand(1));
         Masked = Builder->CreateAnd(LAnd->getOperand(0), Mask);
       } else if (LAnd->getOperand(1) == RAnd->getOperand(1) &&
-                 IsOneHotValue(LAnd->getOperand(0)) &&
-                 IsOneHotValue(RAnd->getOperand(0))) {
+                 isKnownToBeAPowerOfTwo(LAnd->getOperand(0)) &&
+                 isKnownToBeAPowerOfTwo(RAnd->getOperand(0))) {
         Mask = Builder->CreateOr(LAnd->getOperand(0), RAnd->getOperand(0));
         Masked = Builder->CreateAnd(LAnd->getOperand(1), Mask);
       }
index 51f955c2c248dc7a78bba058feed4ea8c2a60214..496d847b5321e0ec91ae2b214889261b9642e7dd 100644 (file)
@@ -16,7 +16,7 @@ bb:
 
 ;CHECK: @foo1_and
 ;CHECK:  shl i32 1, %c1
-;CHECK-NEXT:  shl i32 1, %c2
+;CHECK-NEXT:  lshr i32 -2147483648, %c2
 ;CHECK-NEXT:  or i32
 ;CHECK-NEXT:  and i32
 ;CHECK-NEXT:  icmp ne i32 %1, %0
@@ -24,7 +24,7 @@ bb:
 define i1 @foo1_and(i32 %k, i32 %c1, i32 %c2) {
 bb:
   %tmp = shl i32 1, %c1
-  %tmp4 = shl i32 1, %c2
+  %tmp4 = lshr i32 -2147483648, %c2
   %tmp1 = and i32 %tmp, %k
   %tmp2 = icmp eq i32 %tmp1, 0
   %tmp5 = and i32 %tmp4, %k