InstCombine: Fold away tautological masked compares
authorDavid Majnemer <david.majnemer@gmail.com>
Tue, 18 Nov 2014 09:31:41 +0000 (09:31 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Tue, 18 Nov 2014 09:31:41 +0000 (09:31 +0000)
It is impossible for (x & INT_MAX) == 0 && x == INT_MAX to ever be true.

While this sort of reasoning should normally live in InstSimplify,
the machinery that derives this result is not trivial to split out.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222230 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
test/Transforms/InstCombine/icmp-logical.ll

index 35f0586c914ae3494393958b5fa7159e03f8b78f..55ebcedf9440c40c49fdaa029d91f3c015a27d45 100644 (file)
@@ -776,7 +776,7 @@ static Value *foldLogOpOfMaskedICmps(ICmpInst *LHS, ICmpInst *RHS, bool IsAnd,
     // whole construct
     if (((BCst->getValue() & DCst->getValue()) &
          (CCst->getValue() ^ ECst->getValue())) != 0)
-      return nullptr;
+      return ConstantInt::get(LHS->getType(), !IsAnd);
     Value *newOr1 = Builder->CreateOr(B, D);
     Value *newOr2 = ConstantExpr::getOr(CCst, ECst);
     Value *newAnd = Builder->CreateAnd(A, newOr1);
index d5d8cbc8c26e868b1dd8f653e56b5dc9fa8891b8..faae2016e207595b8aa28a66538b797113953974 100644 (file)
@@ -150,3 +150,23 @@ define i1 @nomask_rhs(i32 %in) {
   %val = or i1 %tst1, %tst2
   ret i1 %val
 }
+
+define i1 @fold_mask_cmps_to_false(i32 %x) {
+; CHECK-LABEL: @fold_mask_cmps_to_false
+; CHECK: ret i1 false
+  %1 = and i32 %x, 2147483647
+  %2 = icmp eq i32 %1, 0
+  %3 = icmp eq i32 %x, 2147483647
+  %4 = and i1 %3, %2
+  ret i1 %4
+}
+
+define i1 @fold_mask_cmps_to_true(i32 %x) {
+; CHECK-LABEL: @fold_mask_cmps_to_true
+; CHECK: ret i1 true
+  %1 = and i32 %x, 2147483647
+  %2 = icmp ne i32 %1, 0
+  %3 = icmp ne i32 %x, 2147483647
+  %4 = or i1 %3, %2
+  ret i1 %4
+}