[PATCH] InstCombine: Combine two icmps into one if the RHSs agree

David Majnemer david.majnemer at gmail.com
Thu Jul 31 11:40:28 PDT 2014


  - We only need to consider the uses of the and operands.

http://reviews.llvm.org/D4744

Files:
  lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  test/Transforms/InstCombine/2008-08-05-And.ll
  test/Transforms/InstCombine/or.ll

Index: lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -809,28 +809,28 @@
   if (Value *V = foldLogOpOfMaskedICmps(LHS, RHS, true, Builder))
     return V;
 
-  // This only handles icmp of constants: (icmp1 A, C1) & (icmp2 B, C2).
   Value *Val = LHS->getOperand(0), *Val2 = RHS->getOperand(0);
-  ConstantInt *LHSCst = dyn_cast<ConstantInt>(LHS->getOperand(1));
-  ConstantInt *RHSCst = dyn_cast<ConstantInt>(RHS->getOperand(1));
-  if (!LHSCst || !RHSCst) return nullptr;
-
-  if (LHSCst == RHSCst && LHSCC == RHSCC) {
-    // (icmp ult A, C) & (icmp ult B, C) --> (icmp ult (A|B), C)
-    // where C is a power of 2
-    if (LHSCC == ICmpInst::ICMP_ULT &&
-        LHSCst->getValue().isPowerOf2()) {
-      Value *NewOr = Builder->CreateOr(Val, Val2);
-      return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
-    }
 
-    // (icmp eq A, 0) & (icmp eq B, 0) --> (icmp eq (A|B), 0)
-    if (LHSCC == ICmpInst::ICMP_EQ && LHSCst->isZero()) {
-      Value *NewOr = Builder->CreateOr(Val, Val2);
-      return Builder->CreateICmp(LHSCC, NewOr, LHSCst);
+  // (icmp CC A, C) & (icmp CC B, C) --> (icmp CC (A|B), C)
+  if (LHS->getOperand(1) == RHS->getOperand(1) && LHSCC == RHSCC) {
+    const Type *Ty = Val->getType();
+    if (Ty->isIntegerTy() ||
+        (Ty->isVectorTy() &&
+         cast<VectorType>(Ty)->getElementType()->isIntegerTy())) {
+      // We are creating two instructions; make sure we are replacing at least
+      // that many.
+      if (LHS->hasOneUse() || RHS->hasOneUse()) {
+        Value *NewOr = Builder->CreateOr(Val, Val2);
+        return Builder->CreateICmp(LHSCC, NewOr, LHS->getOperand(1));
+      }
     }
   }
 
+  // This only handles icmp of constants: (icmp1 A, C1) & (icmp2 B, C2).
+  ConstantInt *LHSCst = dyn_cast<ConstantInt>(LHS->getOperand(1));
+  ConstantInt *RHSCst = dyn_cast<ConstantInt>(RHS->getOperand(1));
+  if (!LHSCst || !RHSCst) return nullptr;
+
   // (trunc x) == C1 & (and x, CA) == C2 -> (and x, CA|CMAX) == C1|C2
   // where CMAX is the all ones value for the truncated type,
   // iff the lower bits of C2 and CA are zero.
Index: test/Transforms/InstCombine/2008-08-05-And.ll
===================================================================
--- test/Transforms/InstCombine/2008-08-05-And.ll
+++ test/Transforms/InstCombine/2008-08-05-And.ll
@@ -1,4 +1,4 @@
-; RUN: opt < %s -instcombine -S | not grep or
+; RUN: opt < %s -instcombine -S | FileCheck %s
 ; PR2629
 
 define void @f(i8* %x) nounwind  {
@@ -13,6 +13,11 @@
 	%s2 = sub i8 %l1, 10
         %c2 = icmp ugt i8 %s2, 2
         %a1 = and i1 %c1, %c2
+; CHECK:      %[[LOAD:.*]] = load i8* %x, align 1
+; CHECK-NEXT: %[[ADD1:.*]] = add i8 %[[LOAD]], -6
+; CHECK-NEXT: %[[ADD2:.*]] = add i8 %[[LOAD]], -10
+; CHECK-NEXT: %[[OR:.*]] = or i8 %[[ADD1]], %[[ADD2]]
+; CHECK-NEXT: %[[ICMP:.*]] = icmp ugt i8 %[[OR]], 2
 	br i1 %a1, label %incompatible, label %okay
 
 okay:
Index: test/Transforms/InstCombine/or.ll
===================================================================
--- test/Transforms/InstCombine/or.ll
+++ test/Transforms/InstCombine/or.ll
@@ -427,3 +427,14 @@
  %or = or i32 %and, %xor
  ret i32 %or
 }
+
+define i1 @test41(i32 %a, i32 %b) {
+  %cmp1 = icmp slt i32 %a, 8
+  %cmp2 = icmp slt i32 %b, 8
+  %ret = and i1 %cmp1, %cmp2
+  ret i1 %ret
+; CHECK-LABEL: test41(
+; CHECK-NEXT: %[[OR:.*]]  = or i32 %a, %b
+; CHECK-NEXT: %[[CMP:.*]] = icmp slt i32 %[[OR]], 8
+; CHECK-NEXT: ret i1 %[[CMP]]
+}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D4744.12077.patch
Type: text/x-patch
Size: 3621 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140731/3124ce08/attachment.bin>


More information about the llvm-commits mailing list