For PR950:

First in a series of patches to convert SetCondInst into ICmpInst and
FCmpInst using only two opcodes and having the instructions contain their
predicate value. Nothing uses these classes yet. More patches to follow.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31867 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer 2006-11-20 01:22:35 +00:00
parent 36699cabc5
commit 45fb3f3cb2
9 changed files with 642 additions and 15 deletions

View File

@ -243,6 +243,91 @@ public:
}
};
//===----------------------------------------------------------------------===//
// 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

View File

@ -126,20 +126,22 @@ HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst)
// 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

View File

@ -414,6 +414,239 @@ public:
}
};
//===----------------------------------------------------------------------===//
// 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
//===----------------------------------------------------------------------===//

View File

@ -169,6 +169,8 @@ public:
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); }
@ -192,6 +194,7 @@ public:
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

View File

@ -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.

View File

@ -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) {

View File

@ -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;

View File

@ -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)); }

View File

@ -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);