aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
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
commit85b5eb050572f787331cc6af573b7f72bd174d79 (patch)
tree298fabb64846804129505d59c99d95c1f6205c5d /lib/Transforms
parentf299184565f5f0ff9e3bbb94dad184fd5a690c2c (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53444 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp32
1 files changed, 22 insertions, 10 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 8cc7c05425..409d29c2a4 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/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);
+ }
}
}