summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-07-11 04:20:58 +0000
committerChris Lattner <sabre@nondot.org>2008-07-11 04:20:58 +0000
commit6af608b8cecaf85ec0c0c670fbe79023e0a0bf45 (patch)
tree16d1a0c220c96c8542b8069972f4f954f7276515
parent4fa8bb343016b2f5913128c473a614bc5fd289f0 (diff)
downloadbcm5719-llvm-6af608b8cecaf85ec0c0c670fbe79023e0a0bf45.tar.gz
bcm5719-llvm-6af608b8cecaf85ec0c0c670fbe79023e0a0bf45.zip
Fix folding of icmp's of i1 where the comparison is signed. The code
was using the algorithm for folding unsigned comparisons which is completely wrong. This has been broken since the signless types change. llvm-svn: 53444
-rw-r--r--llvm/lib/Transforms/Scalar/InstructionCombining.cpp32
-rw-r--r--llvm/test/Transforms/InstCombine/2008-07-10-CastSextBool.ll11
2 files changed, 32 insertions, 11 deletions
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 8cc7c05425b..409d29c2a49 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -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);
+ }
}
}
diff --git a/llvm/test/Transforms/InstCombine/2008-07-10-CastSextBool.ll b/llvm/test/Transforms/InstCombine/2008-07-10-CastSextBool.ll
index f5efefb0a0b..205e57d7973 100644
--- a/llvm/test/Transforms/InstCombine/2008-07-10-CastSextBool.ll
+++ b/llvm/test/Transforms/InstCombine/2008-07-10-CastSextBool.ll
@@ -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
+}
+
OpenPOWER on IntegriCloud