Fix folding of icmp's of i1 where the comparison is signed. The code
authorChris Lattner <sabre@nondot.org>
Fri, 11 Jul 2008 04:20:58 +0000 (04:20 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 11 Jul 2008 04:20:58 +0000 (04:20 +0000)
was using the algorithm for folding unsigned comparisons which is
completely wrong.  This has been broken since the signless types change.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53444 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/2008-07-10-CastSextBool.ll

index 8cc7c05425b953d4f7d53573c25704f7bc6b5c3c..409d29c2a49cbd3967a2e6044ad64c574cdea3f2 100644 (file)
@@ -5196,34 +5196,46 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
   if (Ty == Type::Int1Ty) {
     switch (I.getPredicate()) {
     default: assert(0 && "Invalid icmp instruction!");
-    case ICmpInst::ICMP_EQ: {               // icmp eq bool %A, %B -> ~(A^B)
+    case ICmpInst::ICMP_EQ: {               // icmp eq i1 A, B -> ~(A^B)
       Instruction *Xor = BinaryOperator::CreateXor(Op0, Op1, I.getName()+"tmp");
       InsertNewInstBefore(Xor, I);
       return BinaryOperator::CreateNot(Xor);
     }
-    case ICmpInst::ICMP_NE:                  // icmp eq bool %A, %B -> A^B
+    case ICmpInst::ICMP_NE:                  // icmp eq i1 A, B -> A^B
       return BinaryOperator::CreateXor(Op0, Op1);
 
     case ICmpInst::ICMP_UGT:
-    case ICmpInst::ICMP_SGT:
-      std::swap(Op0, Op1);                   // Change icmp gt -> icmp lt
+      std::swap(Op0, Op1);                   // Change icmp ugt -> icmp ult
       // FALL THROUGH
-    case ICmpInst::ICMP_ULT:
-    case ICmpInst::ICMP_SLT: {               // icmp lt bool A, B -> ~X & Y
+    case ICmpInst::ICMP_ULT:{               // icmp ult i1 A, B -> ~A & B
       Instruction *Not = BinaryOperator::CreateNot(Op0, I.getName()+"tmp");
       InsertNewInstBefore(Not, I);
       return BinaryOperator::CreateAnd(Not, Op1);
     }
+    case ICmpInst::ICMP_SGT:
+      std::swap(Op0, Op1);                   // Change icmp sgt -> icmp slt
+      // FALL THROUGH
+    case ICmpInst::ICMP_SLT: {               // icmp slt i1 A, B -> A & ~B
+      Instruction *Not = BinaryOperator::CreateNot(Op1, I.getName()+"tmp");
+      InsertNewInstBefore(Not, I);
+      return BinaryOperator::CreateAnd(Not, Op0);
+    }
     case ICmpInst::ICMP_UGE:
-    case ICmpInst::ICMP_SGE:
-      std::swap(Op0, Op1);                   // Change icmp ge -> icmp le
+      std::swap(Op0, Op1);                   // Change icmp uge -> icmp ule
       // FALL THROUGH
-    case ICmpInst::ICMP_ULE:
-    case ICmpInst::ICMP_SLE: {               //  icmp le bool %A, %B -> ~A | B
+    case ICmpInst::ICMP_ULE: {               //  icmp ule i1 A, B -> ~A | B
       Instruction *Not = BinaryOperator::CreateNot(Op0, I.getName()+"tmp");
       InsertNewInstBefore(Not, I);
       return BinaryOperator::CreateOr(Not, Op1);
     }
+    case ICmpInst::ICMP_SGE:
+      std::swap(Op0, Op1);                   // Change icmp sge -> icmp sle
+      // FALL THROUGH
+    case ICmpInst::ICMP_SLE: {               //  icmp sle i1 A, B -> A | ~B
+      Instruction *Not = BinaryOperator::CreateNot(Op1, I.getName()+"tmp");
+      InsertNewInstBefore(Not, I);
+      return BinaryOperator::CreateOr(Not, Op0);
+    }
     }
   }
 
index f5efefb0a0be48c7895ce4878d9e51031ce5da1f..205e57d797384aa85cf9d46bdea9eb27747f6381 100644 (file)
@@ -1,8 +1,17 @@
 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {%C = xor i1 %A, true}
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i1 false}
 ; PR2539
 
-define i1 @test(i1 %A) {
+define i1 @test1(i1 %A) {
        %B = zext i1 %A to i32
        %C = icmp slt i32 %B, 1
        ret i1 %C
 }
+
+
+define i1 @test2(i1 zeroext  %b) {
+entry:
+       %cmptmp = icmp slt i1 %b, true          ; <i1> [#uses=1]
+       ret i1 %cmptmp
+}
+