diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/ValueNumbering.cpp | 23 | ||||
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 56 | ||||
-rw-r--r-- | llvm/lib/VMCore/Instruction.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/VMCore/Instructions.cpp | 196 | ||||
-rw-r--r-- | llvm/lib/VMCore/Verifier.cpp | 29 |
5 files changed, 305 insertions, 1 deletions
diff --git a/llvm/lib/Analysis/ValueNumbering.cpp b/llvm/lib/Analysis/ValueNumbering.cpp index 0224a0132fd..03b9f6b3eae 100644 --- a/llvm/lib/Analysis/ValueNumbering.cpp +++ b/llvm/lib/Analysis/ValueNumbering.cpp @@ -75,6 +75,7 @@ namespace { void visitCastInst(CastInst &I); void visitGetElementPtrInst(GetElementPtrInst &I); + void visitCmpInst(CmpInst &I); void handleBinaryInst(Instruction &I); void visitBinaryOperator(Instruction &I) { handleBinaryInst(I); } @@ -124,6 +125,28 @@ void BVNImpl::visitCastInst(CastInst &CI) { } } +void BVNImpl::visitCmpInst(CmpInst &CI1) { + Value *LHS = CI1.getOperand(0); + for (Value::use_iterator UI = LHS->use_begin(), UE = LHS->use_end(); + UI != UE; ++UI) + if (CmpInst *CI2 = dyn_cast<CmpInst>(*UI)) + // Check to see if this compare instruction is not CI, but same opcode, + // same predicate, and in the same function. + if (CI2 != &CI1 && CI2->getOpcode() == CI1.getOpcode() && + CI2->getPredicate() == CI1.getPredicate() && + CI2->getParent()->getParent() == CI1.getParent()->getParent()) + // If the operands are the same + if ((CI2->getOperand(0) == CI1.getOperand(0) && + CI2->getOperand(1) == CI1.getOperand(1)) || + // Or the compare is commutative and the operands are reversed + (CI1.isCommutative() && + CI2->getOperand(0) == CI1.getOperand(1) && + CI2->getOperand(1) == CI1.getOperand(0))) + // Then the instructiosn are identical, add to list. + RetVals.push_back(CI2); +} + + // isIdenticalBinaryInst - Return true if the two binary instructions are // identical. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 11347f9e584..8b9fa863296 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -541,6 +541,8 @@ public: void visitShl(User &I) { visitShift(I, ISD::SHL); } void visitLShr(User &I) { visitShift(I, ISD::SRL); } void visitAShr(User &I) { visitShift(I, ISD::SRA); } + void visitICmp(User &I); + void visitFCmp(User &I); void visitSetCC(User &I, ISD::CondCode SignedOpc, ISD::CondCode UnsignedOpc, ISD::CondCode FPOpc); void visitSetEQ(User &I) { visitSetCC(I, ISD::SETEQ, ISD::SETEQ, @@ -1442,6 +1444,60 @@ void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) { setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2)); } +void SelectionDAGLowering::visitICmp(User &I) { + ICmpInst *IC = cast<ICmpInst>(&I); + SDOperand Op1 = getValue(IC->getOperand(0)); + SDOperand Op2 = getValue(IC->getOperand(1)); + ISD::CondCode Opcode; + switch (IC->getPredicate()) { + case ICmpInst::ICMP_EQ : Opcode = ISD::SETEQ; break; + case ICmpInst::ICMP_NE : Opcode = ISD::SETNE; break; + case ICmpInst::ICMP_UGT : Opcode = ISD::SETUGT; break; + case ICmpInst::ICMP_UGE : Opcode = ISD::SETUGE; break; + case ICmpInst::ICMP_ULT : Opcode = ISD::SETULT; break; + case ICmpInst::ICMP_ULE : Opcode = ISD::SETULE; break; + case ICmpInst::ICMP_SGT : Opcode = ISD::SETGT; break; + case ICmpInst::ICMP_SGE : Opcode = ISD::SETGE; break; + case ICmpInst::ICMP_SLT : Opcode = ISD::SETLT; break; + case ICmpInst::ICMP_SLE : Opcode = ISD::SETLE; break; + default: + assert(!"Invalid ICmp predicate value"); + Opcode = ISD::SETEQ; + break; + } + setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Opcode)); +} + +void SelectionDAGLowering::visitFCmp(User &I) { + FCmpInst *FC = cast<FCmpInst>(&I); + SDOperand Op1 = getValue(FC->getOperand(0)); + SDOperand Op2 = getValue(FC->getOperand(1)); + ISD::CondCode Opcode; + switch (FC->getPredicate()) { + case FCmpInst::FCMP_FALSE : Opcode = ISD::SETFALSE; + case FCmpInst::FCMP_OEQ : Opcode = ISD::SETOEQ; + case FCmpInst::FCMP_OGT : Opcode = ISD::SETOGT; + case FCmpInst::FCMP_OGE : Opcode = ISD::SETOGE; + case FCmpInst::FCMP_OLT : Opcode = ISD::SETOLT; + case FCmpInst::FCMP_OLE : Opcode = ISD::SETOLE; + case FCmpInst::FCMP_ONE : Opcode = ISD::SETONE; + case FCmpInst::FCMP_ORD : Opcode = ISD::SETO; + case FCmpInst::FCMP_UNO : Opcode = ISD::SETUO; + case FCmpInst::FCMP_UEQ : Opcode = ISD::SETUEQ; + case FCmpInst::FCMP_UGT : Opcode = ISD::SETUGT; + case FCmpInst::FCMP_UGE : Opcode = ISD::SETUGE; + case FCmpInst::FCMP_ULT : Opcode = ISD::SETULT; + case FCmpInst::FCMP_ULE : Opcode = ISD::SETULE; + case FCmpInst::FCMP_UNE : Opcode = ISD::SETUNE; + case FCmpInst::FCMP_TRUE : Opcode = ISD::SETTRUE; + default: + assert(!"Invalid FCmp predicate value"); + Opcode = ISD::SETFALSE; + break; + } + setValue(&I, DAG.getSetCC(MVT::i1, Op1, Op2, Opcode)); +} + void SelectionDAGLowering::visitSetCC(User &I,ISD::CondCode SignedOpcode, ISD::CondCode UnsignedOpcode, ISD::CondCode FPOpcode) { diff --git a/llvm/lib/VMCore/Instruction.cpp b/llvm/lib/VMCore/Instruction.cpp index 70b375902dc..64a9e12f82d 100644 --- a/llvm/lib/VMCore/Instruction.cpp +++ b/llvm/lib/VMCore/Instruction.cpp @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Type.h" #include "llvm/Instructions.h" #include "llvm/Function.h" #include "llvm/SymbolTable.h" -#include "llvm/Type.h" #include "llvm/Support/LeakDetector.h" using namespace llvm; diff --git a/llvm/lib/VMCore/Instructions.cpp b/llvm/lib/VMCore/Instructions.cpp index 5ed07cfb7f7..f559c6324e4 100644 --- a/llvm/lib/VMCore/Instructions.cpp +++ b/llvm/lib/VMCore/Instructions.cpp @@ -1290,6 +1290,197 @@ Instruction::BinaryOps SetCondInst::getSwappedCondition(BinaryOps Opcode) { } } + +//===----------------------------------------------------------------------===// +// CmpInst Classes +//===----------------------------------------------------------------------===// + +CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS, + const std::string &Name, Instruction *InsertBefore) + : Instruction(Type::BoolTy, op, Ops, 2, Name, InsertBefore) { + Ops[0].init(LHS, this); + Ops[1].init(RHS, this); + SubclassData = predicate; + if (op == Instruction::ICmp) { + assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE && + predicate <= ICmpInst::LAST_ICMP_PREDICATE && + "Invalid ICmp predicate value"); + const Type* Op0Ty = getOperand(0)->getType(); + const Type* Op1Ty = getOperand(1)->getType(); + assert(Op0Ty == Op1Ty && + "Both operands to ICmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID || + (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isIntegral()) && + "Invalid operand types for ICmp instruction"); + return; + } + assert(op == Instruction::FCmp && "Invalid CmpInst opcode"); + assert(predicate <= FCmpInst::LAST_FCMP_PREDICATE && + "Invalid FCmp predicate value"); + const Type* Op0Ty = getOperand(0)->getType(); + const Type* Op1Ty = getOperand(1)->getType(); + assert(Op0Ty == Op1Ty && + "Both operands to FCmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(Op0Ty->isFloatingPoint() || (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isFloatingPoint()) && + "Invalid operand types for FCmp instruction"); +} + +CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS, + const std::string &Name, BasicBlock *InsertAtEnd) + : Instruction(Type::BoolTy, op, Ops, 2, Name, InsertAtEnd) { + Ops[0].init(LHS, this); + Ops[1].init(RHS, this); + SubclassData = predicate; + if (op == Instruction::ICmp) { + assert(predicate >= ICmpInst::FIRST_ICMP_PREDICATE && + predicate <= ICmpInst::LAST_ICMP_PREDICATE && + "Invalid ICmp predicate value"); + + const Type* Op0Ty = getOperand(0)->getType(); + const Type* Op1Ty = getOperand(1)->getType(); + assert(Op0Ty == Op1Ty && + "Both operands to ICmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID || + (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isIntegral()) && + "Invalid operand types for ICmp instruction"); + return; + } + assert(op == Instruction::FCmp && "Invalid CmpInst opcode"); + assert(predicate <= FCmpInst::LAST_FCMP_PREDICATE && + "Invalid FCmp predicate value"); + const Type* Op0Ty = getOperand(0)->getType(); + const Type* Op1Ty = getOperand(1)->getType(); + assert(Op0Ty == Op1Ty && + "Both operands to FCmp instruction are not of the same type!"); + // Check that the operands are the right type + assert(Op0Ty->isFloatingPoint() || (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isFloatingPoint()) && + "Invalid operand types for FCmp instruction"); +} + +CmpInst * +CmpInst::create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, + const std::string &Name, Instruction *InsertBefore) { + if (Op == Instruction::ICmp) { + return new ICmpInst(ICmpInst::Predicate(predicate), S1, S2, Name, + InsertBefore); + } + return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name, + InsertBefore); +} + +CmpInst * +CmpInst::create(OtherOps Op, unsigned short predicate, Value *S1, Value *S2, + const std::string &Name, BasicBlock *InsertAtEnd) { + if (Op == Instruction::ICmp) { + return new ICmpInst(ICmpInst::Predicate(predicate), S1, S2, Name, + InsertAtEnd); + } + return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name, + InsertAtEnd); +} + +void CmpInst::swapOperands() { + if (ICmpInst *IC = dyn_cast<ICmpInst>(this)) + IC->swapOperands(); + else + cast<FCmpInst>(this)->swapOperands(); +} + +bool CmpInst::isCommutative() { + if (ICmpInst *IC = dyn_cast<ICmpInst>(this)) + return IC->isCommutative(); + return cast<FCmpInst>(this)->isCommutative(); +} + +bool CmpInst::isEquality() { + if (ICmpInst *IC = dyn_cast<ICmpInst>(this)) + return IC->isEquality(); + return cast<FCmpInst>(this)->isEquality(); +} + + +ICmpInst::Predicate ICmpInst::getInversePredicate(Predicate pred) { + switch (pred) { + default: + assert(!"Unknown icmp predicate!"); + case ICMP_EQ: return ICMP_NE; + case ICMP_NE: return ICMP_EQ; + case ICMP_UGT: return ICMP_ULE; + case ICMP_ULT: return ICMP_UGE; + case ICMP_UGE: return ICMP_ULT; + case ICMP_ULE: return ICMP_UGT; + case ICMP_SGT: return ICMP_SLE; + case ICMP_SLT: return ICMP_SGE; + case ICMP_SGE: return ICMP_SLT; + case ICMP_SLE: return ICMP_SGT; + } +} + +ICmpInst::Predicate ICmpInst::getSwappedPredicate(Predicate pred) { + switch (pred) { + default: assert(! "Unknown setcc instruction!"); + case ICMP_EQ: case ICMP_NE: + return pred; + case ICMP_SGT: return ICMP_SLT; + case ICMP_SLT: return ICMP_SGT; + case ICMP_SGE: return ICMP_SLE; + case ICMP_SLE: return ICMP_SGE; + case ICMP_UGT: return ICMP_ULT; + case ICMP_ULT: return ICMP_UGT; + case ICMP_UGE: return ICMP_ULE; + case ICMP_ULE: return ICMP_UGE; + } +} + +FCmpInst::Predicate FCmpInst::getInversePredicate(Predicate pred) { + switch (pred) { + default: + assert(!"Unknown icmp predicate!"); + case FCMP_OEQ: return FCMP_UNE; + case FCMP_ONE: return FCMP_UEQ; + case FCMP_OGT: return FCMP_ULE; + case FCMP_OLT: return FCMP_UGE; + case FCMP_OGE: return FCMP_ULT; + case FCMP_OLE: return FCMP_UGT; + case FCMP_UEQ: return FCMP_ONE; + case FCMP_UNE: return FCMP_OEQ; + case FCMP_UGT: return FCMP_OLE; + case FCMP_ULT: return FCMP_OGE; + case FCMP_UGE: return FCMP_OLT; + case FCMP_ULE: return FCMP_OGT; + case FCMP_ORD: return FCMP_UNO; + case FCMP_UNO: return FCMP_ORD; + case FCMP_TRUE: return FCMP_FALSE; + case FCMP_FALSE: return FCMP_TRUE; + } +} + +FCmpInst::Predicate FCmpInst::getSwappedPredicate(Predicate pred) { + switch (pred) { + default: assert(!"Unknown setcc instruction!"); + case FCMP_FALSE: case FCMP_TRUE: + case FCMP_OEQ: case FCMP_ONE: + case FCMP_UEQ: case FCMP_UNE: + case FCMP_ORD: case FCMP_UNO: + return pred; + case FCMP_OGT: return FCMP_OLT; + case FCMP_OLT: return FCMP_OGT; + case FCMP_OGE: return FCMP_OLE; + case FCMP_OLE: return FCMP_OGE; + case FCMP_UGT: return FCMP_ULT; + case FCMP_ULT: return FCMP_UGT; + case FCMP_UGE: return FCMP_ULE; + case FCMP_ULE: return FCMP_UGE; + } +} + //===----------------------------------------------------------------------===// // SwitchInst Implementation //===----------------------------------------------------------------------===// @@ -1412,6 +1603,11 @@ BinaryOperator *BinaryOperator::clone() const { return create(getOpcode(), Ops[0], Ops[1]); } +CmpInst* CmpInst::clone() const { + return create(Instruction::OtherOps(getOpcode()), getPredicate(), + Ops[0], Ops[1]); +} + MallocInst *MallocInst::clone() const { return new MallocInst(*this); } AllocaInst *AllocaInst::clone() const { return new AllocaInst(*this); } FreeInst *FreeInst::clone() const { return new FreeInst(getOperand(0)); } diff --git a/llvm/lib/VMCore/Verifier.cpp b/llvm/lib/VMCore/Verifier.cpp index 868fc67d51f..065ac3b7750 100644 --- a/llvm/lib/VMCore/Verifier.cpp +++ b/llvm/lib/VMCore/Verifier.cpp @@ -179,6 +179,8 @@ namespace { // Anonymous namespace for class void visitBasicBlock(BasicBlock &BB); void visitPHINode(PHINode &PN); void visitBinaryOperator(BinaryOperator &B); + void visitICmpInst(ICmpInst &IC); + void visitFCmpInst(FCmpInst &FC); void visitShiftInst(ShiftInst &SI); void visitExtractElementInst(ExtractElementInst &EI); void visitInsertElementInst(InsertElementInst &EI); @@ -551,6 +553,33 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) { visitInstruction(B); } +void Verifier::visitICmpInst(ICmpInst& IC) { + // Check that the operands are the same type + const Type* Op0Ty = IC.getOperand(0)->getType(); + const Type* Op1Ty = IC.getOperand(1)->getType(); + Assert1(Op0Ty == Op1Ty, + "Both operands to ICmp instruction are not of the same type!", &IC); + // Check that the operands are the right type + Assert1(Op0Ty->isIntegral() || Op0Ty->getTypeID() == Type::PointerTyID || + (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isIntegral()), + "Invalid operand types for ICmp instruction", &IC); + visitInstruction(IC); +} + +void Verifier::visitFCmpInst(FCmpInst& FC) { + // Check that the operands are the same type + const Type* Op0Ty = FC.getOperand(0)->getType(); + const Type* Op1Ty = FC.getOperand(1)->getType(); + Assert1(Op0Ty == Op1Ty, + "Both operands to FCmp instruction are not of the same type!", &FC); + // Check that the operands are the right type + Assert1(Op0Ty->isFloatingPoint() || (isa<PackedType>(Op0Ty) && + cast<PackedType>(Op0Ty)->getElementType()->isFloatingPoint()), + "Invalid operand types for FCmp instruction", &FC); + visitInstruction(FC); +} + void Verifier::visitShiftInst(ShiftInst &SI) { Assert1(SI.getType()->isInteger(), "Shift must return an integer result!", &SI); |