diff options
author | Chris Lattner <sabre@nondot.org> | 2004-08-11 00:50:51 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-08-11 00:50:51 +0000 |
commit | 5dbef2207ebe5ccc095e14979cd14919e63a1f25 (patch) | |
tree | 0995c90312bd28e9291b073d5187dec032960d5c /lib/Transforms | |
parent | 287433594b635f629409655a0de7a743f7d5d9db (diff) |
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
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index bf0f0e839d..97cdc1196e 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -1392,34 +1392,33 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) { // setcc's with boolean values can always be turned into bitwise operations if (Ty == Type::BoolTy) { - // If this is <, >, or !=, we can change this into a simple xor instruction - if (!isTrueWhenEqual(I)) - return BinaryOperator::createXor(Op0, Op1); - - // 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 + switch (I.getOpcode()) { + default: assert(0 && "Invalid setcc instruction!"); + case Instruction::SetEQ: { // seteq bool %A, %B -> ~(A^B) Instruction *Xor = BinaryOperator::createXor(Op0, Op1, I.getName()+"tmp"); InsertNewInstBefore(Xor, I); return BinaryOperator::createNot(Xor); } + case Instruction::SetNE: + return BinaryOperator::createXor(Op0, Op1); - // Handle the setXe cases... - assert(I.getOpcode() == Instruction::SetGE || - I.getOpcode() == Instruction::SetLE); - - if (I.getOpcode() == Instruction::SetGE) + case Instruction::SetGT: + std::swap(Op0, Op1); // Change setgt -> setlt + // FALL THROUGH + case Instruction::SetLT: { // setlt bool A, B -> ~X & Y + 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 - - // Now we just have the SetLE case. - Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp"); - InsertNewInstBefore(Not, I); - return BinaryOperator::createOr(Not, Op1); + // FALL THROUGH + case Instruction::SetLE: { // setle bool %A, %B -> ~A | B + Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp"); + InsertNewInstBefore(Not, I); + return BinaryOperator::createOr(Not, Op1); + } + } } // See if we are doing a comparison between a constant and an instruction that |