}
};
+//===----------------------------------------------------------------------===//
+// CmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This class is the base class for the comparison instructions.
+/// @brief Abstract base class of comparison instructions.
+class CmpInst: public Instruction {
+ CmpInst(); // do not implement
+protected:
+ CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
+ const std::string &Name = "", Instruction *InsertBefore = 0);
+
+ CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
+ const std::string &Name, BasicBlock *InsertAtEnd);
+
+ Use Ops[2]; // CmpInst instructions always have 2 operands, optimize
+
+public:
+ /// Construct a compare instruction, given the opcode, the predicate and
+ /// the two operands. Optionally (if InstBefore is specified) insert the
+ /// instruction into a BasicBlock right before the specified instruction.
+ /// The specified Instruction is allowed to be a dereferenced end iterator.
+ /// @brief Create a CmpInst
+ static CmpInst *create(OtherOps Op, unsigned short predicate, Value *S1,
+ Value *S2, const std::string &Name = "",
+ Instruction *InsertBefore = 0);
+
+ /// Construct a compare instruction, given the opcode, the predicate and the
+ /// two operands. Also automatically insert this instruction to the end of
+ /// the BasicBlock specified.
+ /// @brief Create a CmpInst
+ static CmpInst *create(OtherOps Op, unsigned short predicate, Value *S1,
+ Value *S2, const std::string &Name,
+ BasicBlock *InsertAtEnd);
+
+ /// @brief Implement superclass method.
+ virtual CmpInst *clone() const;
+
+ /// The predicate for CmpInst is defined by the subclasses but stored in
+ /// the SubclassData field (see Value.h). We allow it to be fetched here
+ /// as the predicate but there is no enum type for it, just the raw unsigned
+ /// short. This facilitates comparison of CmpInst instances without delving
+ /// into the subclasses since predicate values are distinct between the
+ /// CmpInst subclasses.
+ /// @brief Return the predicate for this instruction.
+ unsigned short getPredicate() const {
+ return SubclassData;
+ }
+
+ /// @brief Provide more efficient getOperand methods.
+ Value *getOperand(unsigned i) const {
+ assert(i < 2 && "getOperand() out of range!");
+ return Ops[i];
+ }
+ void setOperand(unsigned i, Value *Val) {
+ assert(i < 2 && "setOperand() out of range!");
+ Ops[i] = Val;
+ }
+
+ /// @brief CmpInst instructions always have 2 operands.
+ unsigned getNumOperands() const { return 2; }
+
+ /// This is just a convenience that dispatches to the subclasses.
+ /// @brief Swap the operands.
+ void swapOperands();
+
+ /// This is just a convenience that dispatches to the subclasses.
+ /// @brief Determine if this CmpInst is commutative.
+ bool isCommutative();
+
+ /// This is just a convenience that dispatches to the subclasses.
+ /// @brief Determine if this is an equals/not equals predicate.
+ bool isEquality();
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const CmpInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::ICmp ||
+ I->getOpcode() == Instruction::FCmp;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
} // End llvm namespace
#endif
// Other operators...
FIRST_OTHER_INST(31)
-HANDLE_OTHER_INST(31, PHI , PHINode ) // PHI node instruction
-HANDLE_OTHER_INST(32, Cast , CastInst ) // Type cast
-HANDLE_OTHER_INST(33, Call , CallInst ) // Call a function
-HANDLE_OTHER_INST(34, Shl , ShiftInst ) // Shift Left operations (logical)
-HANDLE_OTHER_INST(35, LShr , ShiftInst ) // Logical Shift right (unsigned)
-HANDLE_OTHER_INST(36, AShr , ShiftInst ) // Arithmetic shift right (signed)
-HANDLE_OTHER_INST(37, Select , SelectInst ) // select instruction
-HANDLE_OTHER_INST(38, UserOp1, Instruction) // May be used internally in a pass
-HANDLE_OTHER_INST(39, UserOp2, Instruction) // Internal to passes only
-HANDLE_OTHER_INST(40, VAArg , VAArgInst ) // vaarg instruction
-HANDLE_OTHER_INST(41, ExtractElement, ExtractElementInst)// extract from vector.
-HANDLE_OTHER_INST(42, InsertElement, InsertElementInst) // insert into vector
-HANDLE_OTHER_INST(43, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
- LAST_OTHER_INST(43)
+HANDLE_OTHER_INST(31, ICmp , ICmpInst ) // Integer comparison instruction
+HANDLE_OTHER_INST(32, FCmp , FCmpInst ) // Floating point comparison instr.
+HANDLE_OTHER_INST(33, PHI , PHINode ) // PHI node instruction
+HANDLE_OTHER_INST(34, Cast , CastInst ) // Type cast
+HANDLE_OTHER_INST(35, Call , CallInst ) // Call a function
+HANDLE_OTHER_INST(36, Shl , ShiftInst ) // Shift Left operations (logical)
+HANDLE_OTHER_INST(37, LShr , ShiftInst ) // Logical Shift right (unsigned)
+HANDLE_OTHER_INST(38, AShr , ShiftInst ) // Arithmetic shift right (signed)
+HANDLE_OTHER_INST(39, Select , SelectInst ) // select instruction
+HANDLE_OTHER_INST(40, UserOp1, Instruction) // May be used internally in a pass
+HANDLE_OTHER_INST(41, UserOp2, Instruction) // Internal to passes only
+HANDLE_OTHER_INST(42, VAArg , VAArgInst ) // vaarg instruction
+HANDLE_OTHER_INST(43, ExtractElement, ExtractElementInst)// extract from vector.
+HANDLE_OTHER_INST(44, InsertElement, InsertElementInst) // insert into vector
+HANDLE_OTHER_INST(45, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
+ LAST_OTHER_INST(45)
#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST
}
};
+//===----------------------------------------------------------------------===//
+// ICmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This instruction compares its operands according to the predicate given
+/// to the constructor. It only operates on integers, pointers, or packed
+/// vectors of integrals. The two operands must be the same type.
+/// @brief Represent an integer comparison operator.
+class ICmpInst: public CmpInst {
+public:
+ /// This enumeration lists the possible predicates for the ICmpInst. The
+ /// values in the range 0-31 are reserved for FCmpInst while values in the
+ /// range 32-64 are reserved for ICmpInst. This is necessary to ensure the
+ /// predicate values are not overlapping between the classes.
+ enum Predicate {
+ ICMP_EQ = 32, ///< equal
+ ICMP_NE = 33, ///< not equal
+ ICMP_UGT = 34, ///< unsigned greater than
+ ICMP_UGE = 35, ///< unsigned greater or equal
+ ICMP_ULT = 36, ///< unsigned less than
+ ICMP_ULE = 37, ///< unsigned less or equal
+ ICMP_SGT = 38, ///< signed greater than
+ ICMP_SGE = 39, ///< signed greater or equal
+ ICMP_SLT = 40, ///< signed less than
+ ICMP_SLE = 41, ///< signed less or equal
+ FIRST_ICMP_PREDICATE = ICMP_EQ,
+ LAST_ICMP_PREDICATE = ICMP_SLE
+ };
+
+ /// @brief Constructor with insert-before-instruction semantics.
+ ICmpInst(
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const std::string &Name = "", ///< Name of the instruction
+ Instruction *InsertBefore = 0 ///< Where to insert
+ ) : CmpInst(Instruction::ICmp, pred, LHS, RHS, Name, InsertBefore) {
+ }
+
+ /// @brief Constructor with insert-at-block-end semantics.
+ ICmpInst(
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const std::string &Name, ///< Name of the instruction
+ BasicBlock *InsertAtEnd ///< Block to insert into.
+ ) : CmpInst(Instruction::ICmp, pred, LHS, RHS, Name, InsertAtEnd) {
+ }
+
+ /// @brief Return the predicate for this instruction.
+ Predicate getPredicate() const { return Predicate(SubclassData); }
+
+ /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
+ /// @returns the inverse predicate for the instruction's current predicate.
+ /// @brief Return the inverse of the instruction's predicate.
+ Predicate getInversePredicate() const {
+ return getInversePredicate(getPredicate());
+ }
+
+ /// For example, EQ -> NE, UGT -> ULE, SLT -> SGE, etc.
+ /// @returns the inverse predicate for predicate provided in \p pred.
+ /// @brief Return the inverse of a given predicate
+ static Predicate getInversePredicate(Predicate pred);
+
+ /// For example, EQ->EQ, SLE->SGE, ULT->UGT, etc.
+ /// @returns the predicate that would be the result of exchanging the two
+ /// operands of the ICmpInst instruction without changing the result
+ /// produced.
+ /// @brief Return the predicate as if the operands were swapped
+ Predicate getSwappedPredicate() const {
+ return getSwappedPredicate(getPredicate());
+ }
+
+ /// This is a static version that you can use without an instruction
+ /// available.
+ /// @brief Return the predicate as if the operands were swapped.
+ static Predicate getSwappedPredicate(Predicate Opcode);
+
+ /// This also tests for commutativity. If isEquality() returns true then
+ /// the predicate is also commutative. Only the equality predicates are
+ /// commutative.
+ /// @returns true if the predicate of this instruction is EQ or NE.
+ /// @brief Determine if this is an equality predicate.
+ bool isEquality() const {
+ return SubclassData == ICMP_EQ || SubclassData == ICMP_NE;
+ }
+ bool isCommutative() const { return isEquality(); }
+
+ /// @returns true if the predicate is relational (not EQ or NE).
+ /// @brief Determine if this a relational predicate.
+ bool isRelational() const {
+ return !isEquality();
+ }
+
+ /// Exchange the two operands to this instruction in such a way that it does
+ /// not modify the semantics of the instruction. The predicate value may be
+ /// changed to retain the same result if the predicate is order dependent
+ /// (e.g. ult).
+ /// @brief Swap operands and adjust predicate.
+ void swapOperands() {
+ SubclassData = getSwappedPredicate();
+ std::swap(Ops[0], Ops[1]);
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const ICmpInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::ICmp;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+//===----------------------------------------------------------------------===//
+// FCmpInst Class
+//===----------------------------------------------------------------------===//
+
+/// This instruction compares its operands according to the predicate given
+/// to the constructor. It only operates on floating point values or packed
+/// vectors of floating point values. The operands must be identical types.
+/// @brief Represents a floating point comparison operator.
+class FCmpInst: public CmpInst {
+public:
+ /// This enumeration lists the possible predicates for the FCmpInst. Values
+ /// in the range 0-31 are reserved for FCmpInst.
+ enum Predicate {
+ // Opcode U L G E Intuitive operation
+ FCMP_FALSE = 0, ///< 0 0 0 0 Always false (always folded)
+ FCMP_OEQ = 1, ///< 0 0 0 1 True if ordered and equal
+ FCMP_OGT = 2, ///< 0 0 1 0 True if ordered and greater than
+ FCMP_OGE = 3, ///< 0 0 1 1 True if ordered and greater than or equal
+ FCMP_OLT = 4, ///< 0 1 0 0 True if ordered and less than
+ FCMP_OLE = 5, ///< 0 1 0 1 True if ordered and less than or equal
+ FCMP_ONE = 6, ///< 0 1 1 0 True if ordered and operands are unequal
+ FCMP_ORD = 7, ///< 0 1 1 1 True if ordered (no nans)
+ FCMP_UNO = 8, ///< 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
+ FCMP_UEQ = 9, ///< 1 0 0 1 True if unordered or equal
+ FCMP_UGT =10, ///< 1 0 1 0 True if unordered or greater than
+ FCMP_UGE =11, ///< 1 0 1 1 True if unordered, greater than, or equal
+ FCMP_ULT =12, ///< 1 1 0 0 True if unordered or less than
+ FCMP_ULE =13, ///< 1 1 0 1 True if unordered, less than, or equal
+ FCMP_UNE =14, ///< 1 1 1 0 True if unordered or not equal
+ FCMP_TRUE =15, ///< 1 1 1 1 Always true (always folded)
+ FIRST_FCMP_PREDICATE = FCMP_FALSE,
+ LAST_FCMP_PREDICATE = FCMP_TRUE
+ };
+
+ /// @brief Constructor with insert-before-instruction semantics.
+ FCmpInst(
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const std::string &Name = "", ///< Name of the instruction
+ Instruction *InsertBefore = 0 ///< Where to insert
+ ) : CmpInst(Instruction::FCmp, pred, LHS, RHS, Name, InsertBefore) {
+ }
+
+ /// @brief Constructor with insert-at-block-end semantics.
+ FCmpInst(
+ Predicate pred, ///< The predicate to use for the comparison
+ Value *LHS, ///< The left-hand-side of the expression
+ Value *RHS, ///< The right-hand-side of the expression
+ const std::string &Name, ///< Name of the instruction
+ BasicBlock *InsertAtEnd ///< Block to insert into.
+ ) : CmpInst(Instruction::FCmp, pred, LHS, RHS, Name, InsertAtEnd) {
+ }
+
+ /// @brief Return the predicate for this instruction.
+ Predicate getPredicate() const { return Predicate(SubclassData); }
+
+ /// For example, OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
+ /// @returns the inverse predicate for the instructions current predicate.
+ /// @brief Return the inverse of the predicate
+ Predicate getInversePredicate() const {
+ return getInversePredicate(getPredicate());
+ }
+
+ /// For example, OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
+ /// @returns the inverse predicate for \p pred.
+ /// @brief Return the inverse of a given predicate
+ static Predicate getInversePredicate(Predicate pred);
+
+ /// For example, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
+ /// @returns the predicate that would be the result of exchanging the two
+ /// operands of the ICmpInst instruction without changing the result
+ /// produced.
+ /// @brief Return the predicate as if the operands were swapped
+ Predicate getSwappedPredicate() const {
+ return getSwappedPredicate(getPredicate());
+ }
+
+ /// This is a static version that you can use without an instruction
+ /// available.
+ /// @brief Return the predicate as if the operands were swapped.
+ static Predicate getSwappedPredicate(Predicate Opcode);
+
+ /// This also tests for commutativity. If isEquality() returns true then
+ /// the predicate is also commutative. Only the equality predicates are
+ /// commutative.
+ /// @returns true if the predicate of this instruction is EQ or NE.
+ /// @brief Determine if this is an equality predicate.
+ bool isEquality() const {
+ return SubclassData == FCMP_OEQ || SubclassData == FCMP_ONE ||
+ SubclassData == FCMP_UEQ || SubclassData == FCMP_UNE;
+ }
+ bool isCommutative() const { return isEquality(); }
+
+ /// @returns true if the predicate is relational (not EQ or NE).
+ /// @brief Determine if this a relational predicate.
+ bool isRelational() const { return !isEquality(); }
+
+ /// Exchange the two operands to this instruction in such a way that it does
+ /// not modify the semantics of the instruction. The predicate value may be
+ /// changed to retain the same result if the predicate is order dependent
+ /// (e.g. ult).
+ /// @brief Swap operands and adjust predicate.
+ void swapOperands() {
+ SubclassData = getSwappedPredicate();
+ std::swap(Ops[0], Ops[1]);
+ }
+
+ /// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const FCmpInst *) { return true; }
+ static inline bool classof(const Instruction *I) {
+ return I->getOpcode() == Instruction::FCmp;
+ }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+
//===----------------------------------------------------------------------===//
// SetCondInst Class
//===----------------------------------------------------------------------===//
RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);}
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
RetTy visitSetCondInst(SetCondInst &I) { DELEGATE(BinaryOperator);}
+ RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
+ RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
RetTy visitMallocInst(MallocInst &I) { DELEGATE(AllocationInst);}
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(AllocationInst);}
RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); }
RetTy visitTerminatorInst(TerminatorInst &I) { DELEGATE(Instruction); }
RetTy visitBinaryOperator(BinaryOperator &I) { DELEGATE(Instruction); }
RetTy visitAllocationInst(AllocationInst &I) { DELEGATE(Instruction); }
+ RetTy visitCmpInst(CmpInst &I) { DELEGATE(Instruction); }
// If the user wants a 'default' case, they can choose to override this
// function. If this function is not overloaded in the users subclass, then
void visitCastInst(CastInst &I);
void visitGetElementPtrInst(GetElementPtrInst &I);
+ void visitCmpInst(CmpInst &I);
void handleBinaryInst(Instruction &I);
void visitBinaryOperator(Instruction &I) { handleBinaryInst(I); }
}
}
+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.
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,
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) {
//
//===----------------------------------------------------------------------===//
+#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;
}
}
+
+//===----------------------------------------------------------------------===//
+// 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
//===----------------------------------------------------------------------===//
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)); }
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);
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);