[llvm] r185677 - InstCombine: (icmp eq B, 0) | (icmp ult A, B) -> (icmp ule A, B-1)
David Majnemer
david.majnemer at gmail.com
Thu Jul 4 17:31:17 PDT 2013
Author: majnemer
Date: Thu Jul 4 19:31:17 2013
New Revision: 185677
URL: http://llvm.org/viewvc/llvm-project?rev=185677&view=rev
Log:
InstCombine: (icmp eq B, 0) | (icmp ult A, B) -> (icmp ule A, B-1)
This transform allows us to turn IR that looks like:
%1 = icmp eq i64 %b, 0
%2 = icmp ult i64 %a, %b
%3 = or i1 %1, %2
ret i1 %3
into:
%0 = add i64 %b, -1
%1 = icmp uge i64 %0, %a
ret i1 %1
which means we go from lowering:
cmpq %rsi, %rdi
setb %cl
testq %rsi, %rsi
sete %al
orb %cl, %al
ret
to lowering:
decq %rsi
cmpq %rdi, %rsi
setae %al
ret
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
llvm/trunk/test/Transforms/InstCombine/icmp.ll
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp?rev=185677&r1=185676&r2=185677&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp Thu Jul 4 19:31:17 2013
@@ -1477,10 +1477,37 @@ Value *InstCombiner::FoldOrOfICmps(ICmpI
if (Value *V = foldLogOpOfMaskedICmps(LHS, RHS, ICmpInst::ICMP_NE, 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 (LHS->hasOneUse() || RHS->hasOneUse()) {
+ // (icmp eq B, 0) | (icmp ult A, B) -> (icmp ule A, B-1)
+ // (icmp eq B, 0) | (icmp ugt B, A) -> (icmp ule A, B-1)
+ Value *A = 0, *B = 0;
+ if (LHSCC == ICmpInst::ICMP_EQ && LHSCst && LHSCst->isZero()) {
+ B = Val;
+ if (RHSCC == ICmpInst::ICMP_ULT && Val == RHS->getOperand(1))
+ A = Val2;
+ else if (RHSCC == ICmpInst::ICMP_UGT && Val == Val2)
+ A = RHS->getOperand(1);
+ }
+ // (icmp ult A, B) | (icmp eq B, 0) -> (icmp ule A, B-1)
+ // (icmp ugt B, A) | (icmp eq B, 0) -> (icmp ule A, B-1)
+ else if (RHSCC == ICmpInst::ICMP_EQ && RHSCst && RHSCst->isZero()) {
+ B = Val2;
+ if (LHSCC == ICmpInst::ICMP_ULT && Val2 == LHS->getOperand(1))
+ A = Val;
+ else if (LHSCC == ICmpInst::ICMP_UGT && Val2 == Val)
+ A = LHS->getOperand(1);
+ }
+ if (A && B)
+ return Builder->CreateICmp(
+ ICmpInst::ICMP_UGE,
+ Builder->CreateAdd(B, ConstantInt::getSigned(B->getType(), -1)), A);
+ }
+
+ // This only handles icmp of constants: (icmp1 A, C1) | (icmp2 B, C2).
if (LHSCst == 0 || RHSCst == 0) return 0;
if (LHSCst == RHSCst && LHSCC == RHSCC) {
Modified: llvm/trunk/test/Transforms/InstCombine/icmp.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/icmp.ll?rev=185677&r1=185676&r2=185677&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/icmp.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/icmp.ll Thu Jul 4 19:31:17 2013
@@ -1102,3 +1102,14 @@ define i1 @icmp_shl_1_V_ult_2147483648(i
%cmp = icmp ult i32 %shl, 2147483648
ret i1 %cmp
}
+
+; CEHCK: @or_icmp_eq_B_0_icmp_ult_A_B
+; CHECK: [[SUB:%[a-z0-9]+]] = add i64 %b, -1
+; CHECK-NEXT: [[CMP:%[a-z0-9]+]] = icmp uge i64 [[SUB]], %a
+; CHECK-NEXT: ret i1 [[CMP]]
+define i1 @or_icmp_eq_B_0_icmp_ult_A_B(i64 %a, i64 %b) {
+ %1 = icmp eq i64 %b, 0
+ %2 = icmp ult i64 %a, %b
+ %3 = or i1 %1, %2
+ ret i1 %3
+}
More information about the llvm-commits
mailing list