mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-28 06:24:57 +00:00
Fix InstCombine/2004-08-10-BoolSetCC.ll, a bug that is miscompiling
176.gcc. Note that this is apparently not the only bug miscompiling gcc though. :( git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15639 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -1392,34 +1392,33 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
|
|||||||
|
|
||||||
// setcc's with boolean values can always be turned into bitwise operations
|
// setcc's with boolean values can always be turned into bitwise operations
|
||||||
if (Ty == Type::BoolTy) {
|
if (Ty == Type::BoolTy) {
|
||||||
// If this is <, >, or !=, we can change this into a simple xor instruction
|
switch (I.getOpcode()) {
|
||||||
if (!isTrueWhenEqual(I))
|
default: assert(0 && "Invalid setcc instruction!");
|
||||||
return BinaryOperator::createXor(Op0, Op1);
|
case Instruction::SetEQ: { // seteq bool %A, %B -> ~(A^B)
|
||||||
|
|
||||||
// Otherwise we need to make a temporary intermediate instruction and insert
|
|
||||||
// it into the instruction stream. This is what we are after:
|
|
||||||
//
|
|
||||||
// seteq bool %A, %B -> ~(A^B)
|
|
||||||
// setle bool %A, %B -> ~A | B
|
|
||||||
// setge bool %A, %B -> A | ~B
|
|
||||||
//
|
|
||||||
if (I.getOpcode() == Instruction::SetEQ) { // seteq case
|
|
||||||
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 Instruction::SetNE:
|
||||||
|
return BinaryOperator::createXor(Op0, Op1);
|
||||||
|
|
||||||
// Handle the setXe cases...
|
case Instruction::SetGT:
|
||||||
assert(I.getOpcode() == Instruction::SetGE ||
|
std::swap(Op0, Op1); // Change setgt -> setlt
|
||||||
I.getOpcode() == Instruction::SetLE);
|
// FALL THROUGH
|
||||||
|
case Instruction::SetLT: { // setlt bool A, B -> ~X & Y
|
||||||
if (I.getOpcode() == Instruction::SetGE)
|
Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp");
|
||||||
|
InsertNewInstBefore(Not, I);
|
||||||
|
return BinaryOperator::createAnd(Not, Op1);
|
||||||
|
}
|
||||||
|
case Instruction::SetGE:
|
||||||
std::swap(Op0, Op1); // Change setge -> setle
|
std::swap(Op0, Op1); // Change setge -> setle
|
||||||
|
// FALL THROUGH
|
||||||
// Now we just have the SetLE case.
|
case Instruction::SetLE: { // setle bool %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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we are doing a comparison between a constant and an instruction that
|
// See if we are doing a comparison between a constant and an instruction that
|
||||||
|
Reference in New Issue
Block a user