InstCombine: Combine (X+cst) < 0 --> X < -cst

This can happen pretty often in code that looks like:
int foo = bar - 1;
if (foo < 0)
  do stuff

In this case, bar < 1 is an equivalent condition.

This transform requires that the add instruction be annotated with nsw.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@221045 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer 2014-11-01 09:09:51 +00:00
parent 666a51320e
commit f74443e53a
2 changed files with 38 additions and 0 deletions

View File

@ -3015,6 +3015,12 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
if (BO1 && BO1->getOpcode() == Instruction::Add)
C = BO1->getOperand(0), D = BO1->getOperand(1);
// icmp (X+cst) < 0 --> X < -cst
if (NoOp0WrapProblem && ICmpInst::isSigned(Pred) && match(Op1, m_Zero()))
if (ConstantInt *RHSC = dyn_cast_or_null<ConstantInt>(B))
if (!RHSC->isMinValue(/*isSigned=*/true))
return new ICmpInst(Pred, A, ConstantExpr::getNeg(RHSC));
// icmp (X+Y), X -> icmp Y, 0 for equalities or if there is no overflow.
if ((A == Op1 || B == Op1) && NoOp0WrapProblem)
return new ICmpInst(Pred, A == Op1 ? B : A,

View File

@ -1479,3 +1479,35 @@ define i1 @shl_ap1_non_zero_ap2_non_zero_ap1_3(i32 %a) {
%cmp = icmp eq i32 %shl, 50
ret i1 %cmp
}
; CHECK-LABEL: @icmp_sgt_zero_add_nsw
; CHECK-NEXT: icmp sgt i32 %a, -1
define i1 @icmp_sgt_zero_add_nsw(i32 %a) {
%add = add nsw i32 %a, 1
%cmp = icmp sgt i32 %add, 0
ret i1 %cmp
}
; CHECK-LABEL: @icmp_sge_zero_add_nsw
; CHECK-NEXT: icmp sgt i32 %a, -2
define i1 @icmp_sge_zero_add_nsw(i32 %a) {
%add = add nsw i32 %a, 1
%cmp = icmp sge i32 %add, 0
ret i1 %cmp
}
; CHECK-LABEL: @icmp_slt_zero_add_nsw
; CHECK-NEXT: icmp slt i32 %a, -1
define i1 @icmp_slt_zero_add_nsw(i32 %a) {
%add = add nsw i32 %a, 1
%cmp = icmp slt i32 %add, 0
ret i1 %cmp
}
; CHECK-LABEL: @icmp_sle_zero_add_nsw
; CHECK-NEXT: icmp slt i32 %a, 0
define i1 @icmp_sle_zero_add_nsw(i32 %a) {
%add = add nsw i32 %a, 1
%cmp = icmp sle i32 %add, 0
ret i1 %cmp
}