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

suyog suyog.sarda at samsung.com
Thu May 22 03:24:44 PDT 2014


Hi bkramer, rafael, majnemer,

Hi,

This patch implements optimization mentioned in 
http://www.cs.utah.edu/~regehr/souper/output_6.html
where we know that when comparing with a constant whose trailing zero's are less than trailing zero's of LHS, it will never be equal.

C test case :
int a, b;
void fn1() { b = a * ~1 == 1; }

gcc output (X86):
fn1:
	movl	$0, b(%rip)
	ret

LLVM output before patch(X86) at O2 optimization :
fn1:                                    # @fn1
	movl	a(%rip), %eax
	addl	%eax, %eax
	cmpl	$-1, %eax
	sete	%al
	movzbl	%al, %eax
	movl	%eax, b(%rip)
	retq

LLVM Output after patch (X86) at O2 optimization:
fn1:
        movl	$0, b(%rip)
	retq

Added test case for the same.
TODO : Generalize this for all constants, currently implemented for comparing with 1.

Please help in reviewing the patch.

http://reviews.llvm.org/D3868

Files:
  lib/Transforms/InstCombine/InstCombineCompares.cpp
  test/Transforms/InstCombine/icmp.ll

Index: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -2438,6 +2438,18 @@
       // (icmp cond A B) if cond is equality
       return new ICmpInst(I.getPredicate(), A, B);
     }
+    // (icmp eq (a * ~1) 1) -> will always evaluate to false
+    // TODO: generalize this for all constants whose trailing zero's are less
+    // than known trailing zero's of LHS
+    const APInt *AP1;
+    if (I.getPredicate() == ICmpInst::ICMP_EQ && match(Op1, m_APInt(AP1)) &&
+        CI->isOne()) {
+      APInt Op0KnownZero(BitWidth, 0, 1);
+      APInt Op0KnownOne(BitWidth, 0, 1);
+      computeKnownBits(Op0, Op0KnownZero, Op0KnownOne);
+      if (Op0KnownZero.countTrailingOnes() >= 1)
+        return ReplaceInstUsesWith(I, ConstantInt::getFalse(I.getType()));
+    }
 
     // If we have an icmp le or icmp ge instruction, turn it into the
     // appropriate icmp lt or icmp gt instruction.  This allows us to rely on
Index: test/Transforms/InstCombine/icmp.ll
===================================================================
--- test/Transforms/InstCombine/icmp.ll
+++ test/Transforms/InstCombine/icmp.ll
@@ -1365,3 +1365,17 @@
   %2 = icmp slt i32 %1, -10
   ret i1 %2
 }
+
+ 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
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3868.9687.patch
Type: text/x-patch
Size: 1698 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140522/435040ac/attachment.bin>


More information about the llvm-commits mailing list