From de90b76670dfb96d73d80e1d54f3bfc85006cc51 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 3 Nov 2003 04:25:02 +0000 Subject: [PATCH] Implement InstCombine/cast-set.ll: test1, test2, test7 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9670 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Scalar/InstructionCombining.cpp | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 534ba5946e2..87d7528b192 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -1103,7 +1103,7 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) { if (Ty == Type::BoolTy) { // If this is <, >, or !=, we can change this into a simple xor instruction if (!isTrueWhenEqual(I)) - return BinaryOperator::create(Instruction::Xor, Op0, Op1, I.getName()); + return BinaryOperator::create(Instruction::Xor, Op0, Op1); // Otherwise we need to make a temporary intermediate instruction and insert // it into the instruction stream. This is what we are after: @@ -1116,7 +1116,7 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) { Instruction *Xor = BinaryOperator::create(Instruction::Xor, Op0, Op1, I.getName()+"tmp"); InsertNewInstBefore(Xor, I); - return BinaryOperator::createNot(Xor, I.getName()); + return BinaryOperator::createNot(Xor); } // Handle the setXe cases... @@ -1129,7 +1129,7 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) { // Now we just have the SetLE case. Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp"); InsertNewInstBefore(Not, I); - return BinaryOperator::create(Instruction::Or, Not, Op1, I.getName()); + return BinaryOperator::create(Instruction::Or, Not, Op1); } // Check to see if we are doing one of many comparisons against constant @@ -1227,9 +1227,9 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) { if (I.getOpcode() == Instruction::SetGE) // A >= MIN -> TRUE return ReplaceInstUsesWith(I, ConstantBool::True); if (I.getOpcode() == Instruction::SetLE) // A <= MIN -> A == MIN - return BinaryOperator::create(Instruction::SetEQ, Op0,Op1, I.getName()); + return BinaryOperator::create(Instruction::SetEQ, Op0, Op1); if (I.getOpcode() == Instruction::SetGT) // A > MIN -> A != MIN - return BinaryOperator::create(Instruction::SetNE, Op0,Op1, I.getName()); + return BinaryOperator::create(Instruction::SetNE, Op0, Op1); } else if (CI->isMaxValue()) { if (I.getOpcode() == Instruction::SetGT) // A > MAX -> FALSE @@ -1237,29 +1237,55 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) { if (I.getOpcode() == Instruction::SetLE) // A <= MAX -> TRUE return ReplaceInstUsesWith(I, ConstantBool::True); if (I.getOpcode() == Instruction::SetGE) // A >= MAX -> A == MAX - return BinaryOperator::create(Instruction::SetEQ, Op0,Op1, I.getName()); + return BinaryOperator::create(Instruction::SetEQ, Op0, Op1); if (I.getOpcode() == Instruction::SetLT) // A < MAX -> A != MAX - return BinaryOperator::create(Instruction::SetNE, Op0,Op1, I.getName()); + return BinaryOperator::create(Instruction::SetNE, Op0, Op1); // Comparing against a value really close to min or max? } else if (isMinValuePlusOne(CI)) { if (I.getOpcode() == Instruction::SetLT) // A < MIN+1 -> A == MIN - return BinaryOperator::create(Instruction::SetEQ, Op0, - SubOne(CI), I.getName()); + return BinaryOperator::create(Instruction::SetEQ, Op0, SubOne(CI)); if (I.getOpcode() == Instruction::SetGE) // A >= MIN-1 -> A != MIN - return BinaryOperator::create(Instruction::SetNE, Op0, - SubOne(CI), I.getName()); + return BinaryOperator::create(Instruction::SetNE, Op0, SubOne(CI)); } else if (isMaxValueMinusOne(CI)) { if (I.getOpcode() == Instruction::SetGT) // A > MAX-1 -> A == MAX - return BinaryOperator::create(Instruction::SetEQ, Op0, - AddOne(CI), I.getName()); + return BinaryOperator::create(Instruction::SetEQ, Op0, AddOne(CI)); if (I.getOpcode() == Instruction::SetLE) // A <= MAX-1 -> A != MAX - return BinaryOperator::create(Instruction::SetNE, Op0, - AddOne(CI), I.getName()); + return BinaryOperator::create(Instruction::SetNE, Op0, AddOne(CI)); } } + // Test to see if the operands of the setcc are casted versions of other + // values. If the cast can be stripped off both arguments, we do so now. + if (CastInst *CI = dyn_cast(Op0)) + if (CI->getOperand(0)->getType()->isLosslesslyConvertibleTo(CI->getType())&& + !isa(Op1) && + (I.getOpcode() == Instruction::SetEQ || + I.getOpcode() == Instruction::SetNE)) { + // We keep moving the cast from the left operand over to the right + // operand, where it can often be eliminated completely. + Op0 = CI->getOperand(0); + + // If operand #1 is a cast instruction, see if we can eliminate it as + // well. + if (CastInst *CI = dyn_cast(Op1)) + if (CI->getOperand(0)->getType()->isLosslesslyConvertibleTo( + Op0->getType())) + Op1 = CI->getOperand(0); + + // If Op1 is a constant, we can fold the cast into the constant. + if (Op1->getType() != Op0->getType()) + if (Constant *Op1C = dyn_cast(Op1)) { + Op1 = ConstantExpr::getCast(Op1C, Op0->getType()); + } else { + // Otherwise, cast the RHS right before the setcc + Op1 = new CastInst(Op1, Op0->getType(), Op1->getName()); + InsertNewInstBefore(cast(Op1), I); + } + return BinaryOperator::create(I.getOpcode(), Op0, Op1); + } + return Changed ? &I : 0; }