[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