diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp | 35 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/icmp.ll | 126 | ||||
| -rw-r--r-- | llvm/test/Transforms/InstCombine/sub.ll | 2 | 
3 files changed, 143 insertions, 20 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp index f1533ce9fe5..999de340975 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2267,7 +2267,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {        return new ICmpInst(Pred, Constant::getNullValue(Op0->getType()),                            C == Op0 ? D : C); -    // icmp (X+Y), (X+Z) -> icmp Y,Z for equalities or if there is no overflow. +    // icmp (X+Y), (X+Z) -> icmp Y, Z for equalities or if there is no overflow.      if (A && C && (A == C || A == D || B == C || B == D) &&          NoOp0WrapProblem && NoOp1WrapProblem &&          // Try not to increase register pressure. @@ -2286,12 +2286,26 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {      if (BO1 && BO1->getOpcode() == Instruction::Sub)        C = BO1->getOperand(0), D = BO1->getOperand(1); -    // icmp (Y-X), (Z-X) -> icmp Y,Z for equalities or if there is no overflow. +    // icmp (X-Y), X -> icmp 0, Y for equalities or if there is no overflow. +    if (A == Op1 && NoOp0WrapProblem) +      return new ICmpInst(Pred, Constant::getNullValue(Op1->getType()), B); + +    // icmp X, (X-Y) -> icmp Y, 0 for equalities or if there is no overflow. +    if (C == Op0 && NoOp1WrapProblem) +      return new ICmpInst(Pred, D, Constant::getNullValue(Op0->getType())); + +    // icmp (Y-X), (Z-X) -> icmp Y, Z for equalities or if there is no overflow.      if (B && D && B == D && NoOp0WrapProblem && NoOp1WrapProblem &&          // Try not to increase register pressure.          BO0->hasOneUse() && BO1->hasOneUse())        return new ICmpInst(Pred, A, C); +    // icmp (X-Y), (X-Z) -> icmp Z, Y for equalities or if there is no overflow. +    if (A && C && A == C && NoOp0WrapProblem && NoOp1WrapProblem && +        // Try not to increase register pressure. +        BO0->hasOneUse() && BO1->hasOneUse()) +      return new ICmpInst(Pred, D, B); +      if (BO0 && BO1 && BO0->getOpcode() == BO1->getOpcode() &&          BO0->hasOneUse() && BO1->hasOneUse() &&          BO0->getOperand(1) == BO1->getOperand(1)) { @@ -2375,12 +2389,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {    if (I.isEquality()) {      Value *A, *B, *C, *D; -     -    // -x == -y --> x == y -    if (match(Op0, m_Neg(m_Value(A))) && -        match(Op1, m_Neg(m_Value(B)))) -      return new ICmpInst(I.getPredicate(), A, B); -     +      if (match(Op0, m_Xor(m_Value(A), m_Value(B)))) {        if (A == Op1 || B == Op1) {    // (A^B) == A  ->  B == 0          Value *OtherVal = A == Op1 ? B : A; @@ -2415,16 +2424,6 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {                            Constant::getNullValue(A->getType()));      } -    // (A-B) == A  ->  B == 0 -    if (match(Op0, m_Sub(m_Specific(Op1), m_Value(B)))) -      return new ICmpInst(I.getPredicate(), B,  -                          Constant::getNullValue(B->getType())); - -    // A == (A-B)  ->  B == 0 -    if (match(Op1, m_Sub(m_Specific(Op0), m_Value(B)))) -      return new ICmpInst(I.getPredicate(), B, -                          Constant::getNullValue(B->getType())); -      // (X&Z) == (Y&Z) -> (X^Y) & Z == 0      if (Op0->hasOneUse() && Op1->hasOneUse() &&          match(Op0, m_And(m_Value(A), m_Value(B))) &&  diff --git a/llvm/test/Transforms/InstCombine/icmp.ll b/llvm/test/Transforms/InstCombine/icmp.ll index 08718affa02..3150883e7d7 100644 --- a/llvm/test/Transforms/InstCombine/icmp.ll +++ b/llvm/test/Transforms/InstCombine/icmp.ll @@ -235,6 +235,7 @@ define i1 @test24(i64 %i) {  }  ; CHECK: @test25 +; X + Z > Y + Z -> X > Y if there is no overflow.  ; CHECK: %c = icmp sgt i32 %x, %y  ; CHECK: ret i1 %c  define i1 @test25(i32 %x, i32 %y, i32 %z) { @@ -245,11 +246,134 @@ define i1 @test25(i32 %x, i32 %y, i32 %z) {  }  ; CHECK: @test26 -; CHECK: %c = icmp sgt i32 %x, %y +; X + Z > Y + Z -> X > Y if there is no overflow. +; CHECK: %c = icmp ugt i32 %x, %y  ; CHECK: ret i1 %c  define i1 @test26(i32 %x, i32 %y, i32 %z) { +  %lhs = add nuw i32 %x, %z +  %rhs = add nuw i32 %y, %z +  %c = icmp ugt i32 %lhs, %rhs +  ret i1 %c +} + +; CHECK: @test27 +; X - Z > Y - Z -> X > Y if there is no overflow. +; CHECK: %c = icmp sgt i32 %x, %y +; CHECK: ret i1 %c +define i1 @test27(i32 %x, i32 %y, i32 %z) {    %lhs = sub nsw i32 %x, %z    %rhs = sub nsw i32 %y, %z    %c = icmp sgt i32 %lhs, %rhs    ret i1 %c  } + +; CHECK: @test28 +; X - Z > Y - Z -> X > Y if there is no overflow. +; CHECK: %c = icmp ugt i32 %x, %y +; CHECK: ret i1 %c +define i1 @test28(i32 %x, i32 %y, i32 %z) { +  %lhs = sub nuw i32 %x, %z +  %rhs = sub nuw i32 %y, %z +  %c = icmp ugt i32 %lhs, %rhs +  ret i1 %c +} + +; CHECK: @test29 +; X + Y > X -> Y > 0 if there is no overflow. +; CHECK: %c = icmp sgt i32 %y, 0 +; CHECK: ret i1 %c +define i1 @test29(i32 %x, i32 %y) { +  %lhs = add nsw i32 %x, %y +  %c = icmp sgt i32 %lhs, %x +  ret i1 %c +} + +; CHECK: @test30 +; X + Y > X -> Y > 0 if there is no overflow. +; CHECK: %c = icmp ne i32 %y, 0 +; CHECK: ret i1 %c +define i1 @test30(i32 %x, i32 %y) { +  %lhs = add nuw i32 %x, %y +  %c = icmp ugt i32 %lhs, %x +  ret i1 %c +} + +; CHECK: @test31 +; X > X + Y -> 0 > Y if there is no overflow. +; CHECK: %c = icmp slt i32 %y, 0 +; CHECK: ret i1 %c +define i1 @test31(i32 %x, i32 %y) { +  %rhs = add nsw i32 %x, %y +  %c = icmp sgt i32 %x, %rhs +  ret i1 %c +} + +; CHECK: @test32 +; X > X + Y -> 0 > Y if there is no overflow. +; CHECK: ret i1 false +define i1 @test32(i32 %x, i32 %y) { +  %rhs = add nuw i32 %x, %y +  %c = icmp ugt i32 %x, %rhs +  ret i1 %c +} + +; CHECK: @test33 +; X - Y > X -> 0 > Y if there is no overflow. +; CHECK: %c = icmp slt i32 %y, 0 +; CHECK: ret i1 %c +define i1 @test33(i32 %x, i32 %y) { +  %lhs = sub nsw i32 %x, %y +  %c = icmp sgt i32 %lhs, %x +  ret i1 %c +} + +; CHECK: @test34 +; X - Y > X -> 0 > Y if there is no overflow. +; CHECK: ret i1 false +define i1 @test34(i32 %x, i32 %y) { +  %lhs = sub nuw i32 %x, %y +  %c = icmp ugt i32 %lhs, %x +  ret i1 %c +} + +; CHECK: @test35 +; X > X - Y -> Y > 0 if there is no overflow. +; CHECK: %c = icmp sgt i32 %y, 0 +; CHECK: ret i1 %c +define i1 @test35(i32 %x, i32 %y) { +  %rhs = sub nsw i32 %x, %y +  %c = icmp sgt i32 %x, %rhs +  ret i1 %c +} + +; CHECK: @test36 +; X > X - Y -> Y > 0 if there is no overflow. +; CHECK: %c = icmp ne i32 %y, 0 +; CHECK: ret i1 %c +define i1 @test36(i32 %x, i32 %y) { +  %rhs = sub nuw i32 %x, %y +  %c = icmp ugt i32 %x, %rhs +  ret i1 %c +} + +; CHECK: @test37 +; X - Y > X - Z -> Z > Y if there is no overflow. +; CHECK: %c = icmp sgt i32 %z, %y +; CHECK: ret i1 %c +define i1 @test37(i32 %x, i32 %y, i32 %z) { +  %lhs = sub nsw i32 %x, %y +  %rhs = sub nsw i32 %x, %z +  %c = icmp sgt i32 %lhs, %rhs +  ret i1 %c +} + +; CHECK: @test38 +; X - Y > X - Z -> Z > Y if there is no overflow. +; CHECK: %c = icmp ugt i32 %z, %y +; CHECK: ret i1 %c +define i1 @test38(i32 %x, i32 %y, i32 %z) { +  %lhs = sub nuw i32 %x, %y +  %rhs = sub nuw i32 %x, %z +  %c = icmp ugt i32 %lhs, %rhs +  ret i1 %c +} diff --git a/llvm/test/Transforms/InstCombine/sub.ll b/llvm/test/Transforms/InstCombine/sub.ll index 778a1b9db5d..9656a7e862a 100644 --- a/llvm/test/Transforms/InstCombine/sub.ll +++ b/llvm/test/Transforms/InstCombine/sub.ll @@ -209,7 +209,7 @@ define i1 @test22(i32 %a, i32 %b) zeroext nounwind  {  	%tmp5 = icmp eq i32 %tmp2, %tmp4	  	ret i1 %tmp5  ; CHECK: @test22 -; CHECK: %tmp5 = icmp eq i32 %a, %b +; CHECK: %tmp5 = icmp eq i32 %b, %a  ; CHECK: ret i1 %tmp5  }  | 

