From: Chris Lattner Date: Wed, 11 Aug 2004 00:50:51 +0000 (+0000) Subject: Fix InstCombine/2004-08-10-BoolSetCC.ll, a bug that is miscompiling X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=5dbef2207ebe5ccc095e14979cd14919e63a1f25;p=oota-llvm.git 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 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index bf0f0e839d0..97cdc1196ea 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