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
This commit is contained in:
Chris Lattner 2008-07-11 04:20:58 +00:00
parent 4fa8bb3430
commit 6af608b8ce
2 changed files with 33 additions and 12 deletions

View 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_UGE:
case ICmpInst::ICMP_SGE:
std::swap(Op0, Op1); // Change icmp ge -> icmp le
case ICmpInst::ICMP_SGT:
std::swap(Op0, Op1); // Change icmp sgt -> icmp slt
// FALL THROUGH
case ICmpInst::ICMP_ULE:
case ICmpInst::ICMP_SLE: { // icmp le bool %A, %B -> ~A | B
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:
std::swap(Op0, Op1); // Change icmp uge -> icmp ule
// FALL THROUGH
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);
}
}
}

View 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
}