[PATCH] InstCombineCompare with constant return false if we know it is never going to be equal

suyog suyog.sarda at samsung.com
Wed Jun 4 05:05:39 PDT 2014


Hi David, Duncan, all,

As per Duncan's suggestion, i have generalized this case, where now i am comparing the KnownBits of LHS and RHS. 
If the KnownBits differ, then icmp eq always return false while icmp ne always returns true.

If a bit is known to be zero for A and known to be one for B then A and B cannot be equal.  
Likewise, if a bit if known to be one for A and known to be zero for B then A != B.

Thus, if A_Known_Zero & B_Known_One != 0 then A != B.  Same if A_Known_One & B_Known_Zero != 0.

I was getting one regression for "test/Transforms/InstCombine/align-2d-gep.ll" with my patch.
I have slightly modified this test case. 

Earlier we were comparing a loop variable with 557 for exit condition. The loop variable was initialized to 0 and was being increased by 2. 
Before my patch, there was no way to determine if " icmp eq i, 557" will be true or false. 
However, now we have that logic, it was always evaluating to false, which made the loop exit condition false, making the inner loop as infinite.
I am now comparing with 556 instead of 557, which doesn't omit the exit condition. There is no regression now.

Please help in reviewing the patch.

Thanks!

http://reviews.llvm.org/D3868

Files:
  lib/Analysis/InstructionSimplify.cpp
  test/Transforms/InstCombine/align-2d-gep.ll
  test/Transforms/InstSimplify/compare.ll

Index: lib/Analysis/InstructionSimplify.cpp
===================================================================
--- lib/Analysis/InstructionSimplify.cpp
+++ lib/Analysis/InstructionSimplify.cpp
@@ -1990,6 +1990,34 @@
     }
   }
 
+  // If the KnownBits of LHS and RHS at same bit position differ,
+  // LHS and RHS are not equal.
+  if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
+      uint32_t BitWidth = CI->getBitWidth();
+      APInt LHSKnownZero(BitWidth, 0, 1);
+      APInt LHSKnownOne(BitWidth, 0, 1);
+      computeKnownBits(LHS, LHSKnownZero, LHSKnownOne);
+      APInt RHSKnownZero(BitWidth, 0, 1);
+      APInt RHSKnownOne(BitWidth, 0, 1);
+      computeKnownBits(RHS, RHSKnownZero, RHSKnownOne);
+      switch (Pred) {
+      // TODO: Handle for other icmp instructions.
+      default:
+        break;
+      case ICmpInst::ICMP_EQ: {
+        if (((LHSKnownOne & RHSKnownZero) != 0) ||
+            ((LHSKnownZero & RHSKnownOne) != 0))
+          return ConstantInt::getFalse(CI->getContext());
+        break;
+      }
+      case ICmpInst::ICMP_NE:
+        if (((LHSKnownOne & RHSKnownZero) != 0) ||
+            ((LHSKnownZero & RHSKnownOne) != 0))
+          return ConstantInt::getTrue(CI->getContext());
+        break;
+      }
+    }
+
   // See if we are doing a comparison with a constant integer.
   if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
     // Rule out tautological comparisons (eg., ult 0 or uge 0).
Index: test/Transforms/InstCombine/align-2d-gep.ll
===================================================================
--- test/Transforms/InstCombine/align-2d-gep.ll
+++ test/Transforms/InstCombine/align-2d-gep.ll
@@ -31,7 +31,7 @@
   store <2 x double><double 0.0, double 0.0>, <2 x double>* %r, align 8
 
   %indvar.next = add i64 %j, 2
-  %exitcond = icmp eq i64 %indvar.next, 557
+  %exitcond = icmp eq i64 %indvar.next, 556
   br i1 %exitcond, label %bb11, label %bb1
 
 bb11:
Index: test/Transforms/InstSimplify/compare.ll
===================================================================
--- test/Transforms/InstSimplify/compare.ll
+++ test/Transforms/InstSimplify/compare.ll
@@ -883,3 +883,27 @@
 ; CHECK: ret i1 false
 }
 
+ at a = common global i32 0, align 4
+ at b = common global i32 0, align 4
+
+; CHECK-LABEL: @icmp_eq_const
+; CHECK-NEXT: store i32 0, i32* @b
+define void @icmp_eq_const() nounwind {
+ %1 = load i32* @a, align 4
+ %2 = mul nsw i32 %1, -2
+ %3 = icmp eq i32 %2, 1
+ %4 = zext i1 %3 to i32
+ store i32 %4, i32* @b, align 4
+ ret void
+}
+
+; CHECK-LABEL: @icmp_ne_const
+; CHECK-NEXT: store i32 1, i32* @b
+define void @icmp_ne_const() nounwind {
+ %1 = load i32* @a, align 4
+ %2 = mul nsw i32 %1, -2
+ %3 = icmp ne i32 %2, 1
+ %4 = zext i1 %3 to i32
+ store i32 %4, i32* @b, align 4
+ ret void
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3868.10089.patch
Type: text/x-patch
Size: 2780 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140604/81fa47c8/attachment.bin>


More information about the llvm-commits mailing list