Index: lib/Analysis/CFG.cpp
===================================================================
--- lib/Analysis/CFG.cpp	(revision 216063)
+++ lib/Analysis/CFG.cpp	(working copy)
@@ -582,26 +582,78 @@
       IntFirst = false;
     }
 
-    if (!IntLiteral || !BoolExpr->isKnownToHaveBooleanValue())
+    if (!IntLiteral)
       return TryResult();
 
-    llvm::APInt IntValue = IntLiteral->getValue();
-    if ((IntValue == 1) || (IntValue == 0))
-      return TryResult();
+    const BinaryOperator *BitOp = dyn_cast<BinaryOperator>(BoolExpr);
+    if (BitOp &&
+        (BitOp->getOpcode() == BO_And || BitOp->getOpcode() == BO_Or)) {
+      const Expr *LHSExpr2 = BitOp->getLHS()->IgnoreParens();
+      const Expr *RHSExpr2 = BitOp->getRHS()->IgnoreParens();
 
-    bool IntLarger = IntLiteral->getType()->isUnsignedIntegerType() ||
-                     !IntValue.isNegative();
+      const IntegerLiteral *IntLiteral2 = dyn_cast<IntegerLiteral>(LHSExpr2);
 
-    BinaryOperatorKind Bok = B->getOpcode();
-    if (Bok == BO_GT || Bok == BO_GE) {
-      // Always true for 10 > bool and bool > -1
-      // Always false for -1 > bool and bool > 10
-      return TryResult(IntFirst == IntLarger);
-    } else {
-      // Always true for -1 < bool and bool < 10
-      // Always false for 10 < bool and bool < -1
-      return TryResult(IntFirst != IntLarger);
+      if (!IntLiteral2)
+        IntLiteral2 = dyn_cast<IntegerLiteral>(RHSExpr2);
+
+      if (!IntLiteral2)
+        return TryResult();
+
+      llvm::APInt L1 = IntLiteral->getValue();
+      llvm::APInt L2 = IntLiteral2->getValue();
+      if (BitOp->getOpcode() == BO_And) {
+        if ((L2.ult(L1) && B->getOpcode() == BO_LT) ||
+            (L2.ule(L1) && B->getOpcode() == BO_LE)) {
+          if (BuildOpts.Observer)
+            BuildOpts.Observer->compareBitwiseEquality(B, true);
+          return TryResult(true);
+        } else if ((L2.ule(L1) && B->getOpcode() == BO_GT) ||
+                   (L2.ult(L1) && B->getOpcode() == BO_GE)) {
+          if (BuildOpts.Observer)
+            BuildOpts.Observer->compareBitwiseEquality(B, false);
+          return TryResult(false);
+        } else if (L1 == 0 && B->getOpcode() == BO_GE) {
+          if (BuildOpts.Observer)
+            BuildOpts.Observer->compareBitwiseEquality(B, true);
+          return TryResult(true);
+        } else if (L1 == 0 && B->getOpcode() == BO_LT) {
+          if (BuildOpts.Observer)
+            BuildOpts.Observer->compareBitwiseEquality(B, false);
+          return TryResult(false);
+        }
+      } else if (BitOp->getOpcode() == BO_Or) {
+        if ((L2.uge(L1) && B->getOpcode() == BO_LT) ||
+            (L2.ugt(L1) && B->getOpcode() == BO_LE)) {
+          if (BuildOpts.Observer)
+            BuildOpts.Observer->compareBitwiseEquality(B, false);
+          return TryResult(false);
+        } else if ((L2.ugt(L1) && B->getOpcode() == BO_GT) ||
+                   (L2.uge(L1) && B->getOpcode() == BO_GE)) {
+          if (BuildOpts.Observer)
+            BuildOpts.Observer->compareBitwiseEquality(B, true);
+          return TryResult(true);
+        }
+      }
+    } else if (BoolExpr->isKnownToHaveBooleanValue()) {
+      llvm::APInt IntValue = IntLiteral->getValue();
+      if ((IntValue == 1) || (IntValue == 0))
+        return TryResult();
+
+      bool IntLarger = IntLiteral->getType()->isUnsignedIntegerType() ||
+                       !IntValue.isNegative();
+
+      BinaryOperatorKind Bok = B->getOpcode();
+      if (Bok == BO_GT || Bok == BO_GE) {
+        // Always true for 10 > bool and bool > -1
+        // Always false for -1 > bool and bool > 10
+        return TryResult(IntFirst == IntLarger);
+      } else {
+        // Always true for -1 < bool and bool < 10
+        // Always false for 10 < bool and bool < -1
+        return TryResult(IntFirst != IntLarger);
+      }
     }
+    return TryResult();
   }
 
   /// Find an incorrect equality comparison. Either with an expression
Index: test/Sema/warn-bitwise-compare.c
===================================================================
--- test/Sema/warn-bitwise-compare.c	(revision 216063)
+++ test/Sema/warn-bitwise-compare.c	(working copy)
@@ -25,4 +25,46 @@
 
   if ((x & mydefine) == 8) {}
   if ((x | mydefine) == 4) {}
+
+  if ((x&0) >= 1) {}  // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x&0) > 1) {}   // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x&0) < 1) {}   // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((x&0) <= 1) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+
+  if ((x&64) >= 0) {} // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((x&64) > 0) {}
+  if ((x&64) < 0) {}  // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x&64) <= 0) {}
+
+  if ((x&0) >= 0) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((x&0) > 0) {}   // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x&0) < 0) {}   // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x&0) <= 0) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+
+  if ((x&64) < 64) {}
+  if ((x&64) < 65) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((x&65) < 64) {}
+  if ((64&x) <= 64) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((x&64) <= 65) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((x&65) <= 64) {}
+  if ((x&64) > 64) {}  // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x&64) > 65) {}  // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x&65) > 64) {}
+  if ((x&64) >= 64) {}
+  if ((x&64) >= 65) {}  // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x&65) >= 64) {}
+  if ((x|0x40) < 64) {}  // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x|64) < 65) {}
+  if ((65|x) < 64) {}  // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x|64) <= 64) {}
+  if ((x|64) <= 65) {}
+  if ((x|65) <= 64) {}  // expected-warning {{bitwise comparison always evaluates to false}}
+  if ((x|64) > 64) {}
+  if ((x|64) > 0x100) {}
+  if ((x|65) > 64) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((x|64) >= 64) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+  if ((x|64) >= 65) {}
+  if ((x|0x91) >= 0x11) {}  // expected-warning {{bitwise comparison always evaluates to true}}
+
+  if ((x&mydefine) < 65) {}
 }
