mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-22 13:29:44 +00:00
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
This commit is contained in:
parent
f299184565
commit
85b5eb0505
@ -5196,34 +5196,46 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
|
|||||||
if (Ty == Type::Int1Ty) {
|
if (Ty == Type::Int1Ty) {
|
||||||
switch (I.getPredicate()) {
|
switch (I.getPredicate()) {
|
||||||
default: assert(0 && "Invalid icmp instruction!");
|
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");
|
Instruction *Xor = BinaryOperator::CreateXor(Op0, Op1, I.getName()+"tmp");
|
||||||
InsertNewInstBefore(Xor, I);
|
InsertNewInstBefore(Xor, I);
|
||||||
return BinaryOperator::CreateNot(Xor);
|
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);
|
return BinaryOperator::CreateXor(Op0, Op1);
|
||||||
|
|
||||||
case ICmpInst::ICMP_UGT:
|
case ICmpInst::ICMP_UGT:
|
||||||
case ICmpInst::ICMP_SGT:
|
std::swap(Op0, Op1); // Change icmp ugt -> icmp ult
|
||||||
std::swap(Op0, Op1); // Change icmp gt -> icmp lt
|
|
||||||
// FALL THROUGH
|
// FALL THROUGH
|
||||||
case ICmpInst::ICMP_ULT:
|
case ICmpInst::ICMP_ULT:{ // icmp ult i1 A, B -> ~A & B
|
||||||
case ICmpInst::ICMP_SLT: { // icmp lt bool A, B -> ~X & Y
|
|
||||||
Instruction *Not = BinaryOperator::CreateNot(Op0, I.getName()+"tmp");
|
Instruction *Not = BinaryOperator::CreateNot(Op0, I.getName()+"tmp");
|
||||||
InsertNewInstBefore(Not, I);
|
InsertNewInstBefore(Not, I);
|
||||||
return BinaryOperator::CreateAnd(Not, Op1);
|
return BinaryOperator::CreateAnd(Not, Op1);
|
||||||
}
|
}
|
||||||
case ICmpInst::ICMP_UGE:
|
case ICmpInst::ICMP_SGT:
|
||||||
case ICmpInst::ICMP_SGE:
|
std::swap(Op0, Op1); // Change icmp sgt -> icmp slt
|
||||||
std::swap(Op0, Op1); // Change icmp ge -> icmp le
|
|
||||||
// FALL THROUGH
|
// FALL THROUGH
|
||||||
case ICmpInst::ICMP_ULE:
|
case ICmpInst::ICMP_SLT: { // icmp slt i1 A, B -> A & ~B
|
||||||
case ICmpInst::ICMP_SLE: { // icmp le bool %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");
|
Instruction *Not = BinaryOperator::CreateNot(Op0, I.getName()+"tmp");
|
||||||
InsertNewInstBefore(Not, I);
|
InsertNewInstBefore(Not, I);
|
||||||
return BinaryOperator::CreateOr(Not, Op1);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {%C = xor i1 %A, true}
|
||||||
|
; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret i1 false}
|
||||||
; PR2539
|
; PR2539
|
||||||
|
|
||||||
define i1 @test(i1 %A) {
|
define i1 @test1(i1 %A) {
|
||||||
%B = zext i1 %A to i32
|
%B = zext i1 %A to i32
|
||||||
%C = icmp slt i32 %B, 1
|
%C = icmp slt i32 %B, 1
|
||||||
ret i1 %C
|
ret i1 %C
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
define i1 @test2(i1 zeroext %b) {
|
||||||
|
entry:
|
||||||
|
%cmptmp = icmp slt i1 %b, true ; <i1> [#uses=1]
|
||||||
|
ret i1 %cmptmp
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user