summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/ValueNumbering.cpp23
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp56
-rw-r--r--llvm/lib/VMCore/Instruction.cpp2
-rw-r--r--llvm/lib/VMCore/Instructions.cpp196
-rw-r--r--llvm/lib/VMCore/Verifier.cpp29
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);
OpenPOWER on IntegriCloud