Add two new instructions to the llvm IR, vicmp and vfcmp. see updated LangRef

for details.  CodeGen support coming in a follow up patch


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50985 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nate Begeman 2008-05-12 19:01:56 +00:00
parent 7c2e4f2fc5
commit ac80ade158
18 changed files with 2032 additions and 1538 deletions

View File

@ -140,6 +140,8 @@
<ol>
<li><a href="#i_icmp">'<tt>icmp</tt>' Instruction</a></li>
<li><a href="#i_fcmp">'<tt>fcmp</tt>' Instruction</a></li>
<li><a href="#i_vicmp">'<tt>vicmp</tt>' Instruction</a></li>
<li><a href="#i_vfcmp">'<tt>vfcmp</tt>' Instruction</a></li>
<li><a href="#i_phi">'<tt>phi</tt>' Instruction</a></li>
<li><a href="#i_select">'<tt>select</tt>' Instruction</a></li>
<li><a href="#i_call">'<tt>call</tt>' Instruction</a></li>
@ -1680,6 +1682,12 @@ following is the syntax for constant expressions:</p>
<dt><b><tt>fcmp COND ( VAL1, VAL2 )</tt></b></dt>
<dd>Performs the <a href="#i_fcmp">fcmp operation</a> on constants.</dd>
<dt><b><tt>vicmp COND ( VAL1, VAL2 )</tt></b></dt>
<dd>Performs the <a href="#i_vicmp">vicmp operation</a> on constants.</dd>
<dt><b><tt>vfcmp COND ( VAL1, VAL2 )</tt></b></dt>
<dd>Performs the <a href="#i_vfcmp">vfcmp operation</a> on constants.</dd>
<dt><b><tt>extractelement ( VAL, IDX )</tt></b></dt>
<dd>Perform the <a href="#i_extractelement">extractelement
@ -3672,9 +3680,9 @@ a value, just a keyword. The possible condition code are:
<a href="#t_floating">floating point</a> typed. They must have identical
types.</p>
<h5>Semantics:</h5>
<p>The '<tt>fcmp</tt>' compares <tt>var1</tt> and <tt>var2</tt> according to
the condition code given as <tt>cond</tt>. The comparison performed always
yields a <a href="#t_primitive">i1</a> result, as follows:
<p>The '<tt>fcmp</tt>' instruction compares <tt>var1</tt> and <tt>var2</tt>
according to the condition code given as <tt>cond</tt>. The comparison performed
always yields a <a href="#t_primitive">i1</a> result, as follows:
<ol>
<li><tt>false</tt>: always yields <tt>false</tt>, regardless of operands.</li>
<li><tt>oeq</tt>: yields <tt>true</tt> if both operands are not a QNAN and
@ -3714,6 +3722,106 @@ yields a <a href="#t_primitive">i1</a> result, as follows:
</pre>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
<a name="i_vicmp">'<tt>vicmp</tt>' Instruction</a>
</div>
<div class="doc_text">
<h5>Syntax:</h5>
<pre> &lt;result&gt; = vicmp &lt;cond&gt; &lt;ty&gt; &lt;var1&gt;, &lt;var2&gt; <i>; yields {ty}:result</i>
</pre>
<h5>Overview:</h5>
<p>The '<tt>vicmp</tt>' instruction returns an integer vector value based on
element-wise comparison of its two integer vector operands.</p>
<h5>Arguments:</h5>
<p>The '<tt>vicmp</tt>' instruction takes three operands. The first operand is
the condition code indicating the kind of comparison to perform. It is not
a value, just a keyword. The possible condition code are:
<ol>
<li><tt>eq</tt>: equal</li>
<li><tt>ne</tt>: not equal </li>
<li><tt>ugt</tt>: unsigned greater than</li>
<li><tt>uge</tt>: unsigned greater or equal</li>
<li><tt>ult</tt>: unsigned less than</li>
<li><tt>ule</tt>: unsigned less or equal</li>
<li><tt>sgt</tt>: signed greater than</li>
<li><tt>sge</tt>: signed greater or equal</li>
<li><tt>slt</tt>: signed less than</li>
<li><tt>sle</tt>: signed less or equal</li>
</ol>
<p>The remaining two arguments must be <a href="#t_vector">vector</a> of
<a href="#t_integer">integer</a> typed. They must also be identical types.</p>
<h5>Semantics:</h5>
<p>The '<tt>vicmp</tt>' instruction compares <tt>var1</tt> and <tt>var2</tt>
according to the condition code given as <tt>cond</tt>. The comparison yields a
<a href="#t_vector">vector</a> of <a href="#t_integer">integer</a> result, of
identical type as the values being compared. The most significant bit in each
element is 1 if the element-wise comparison evaluates to true, and is 0
otherwise. All other bits of the result are undefined. The condition codes
are evaluated identically to the <a href="#i_icmp">'<tt>icmp</tt>'
instruction</a>.
<h5>Example:</h5>
<pre>
&lt;result&gt; = vicmp eq <2 x i32> < i32 4, i32 0 >, < i32 5, i32 0 > <i>; yields: result=<2 x i32> < i32 0, i32 -1 ></i>
&lt;result&gt; = vicmp ult <2 x i8> < i8 1, i8 2 >, < i8 2, i8 2> <i>; yields: result=<2 x i8> < i8 -1, i8 0 ></i>
</pre>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
<a name="i_vfcmp">'<tt>vfcmp</tt>' Instruction</a>
</div>
<div class="doc_text">
<h5>Syntax:</h5>
<pre> &lt;result&gt; = vfcmp &lt;cond&gt; &lt;ty&gt; &lt;var1&gt;, &lt;var2&gt;</pre>
<h5>Overview:</h5>
<p>The '<tt>vfcmp</tt>' instruction returns an integer vector value based on
element-wise comparison of its two floating point vector operands. The output
elements have the same width as the input elements.</p>
<h5>Arguments:</h5>
<p>The '<tt>vfcmp</tt>' instruction takes three operands. The first operand is
the condition code indicating the kind of comparison to perform. It is not
a value, just a keyword. The possible condition code are:
<ol>
<li><tt>false</tt>: no comparison, always returns false</li>
<li><tt>oeq</tt>: ordered and equal</li>
<li><tt>ogt</tt>: ordered and greater than </li>
<li><tt>oge</tt>: ordered and greater than or equal</li>
<li><tt>olt</tt>: ordered and less than </li>
<li><tt>ole</tt>: ordered and less than or equal</li>
<li><tt>one</tt>: ordered and not equal</li>
<li><tt>ord</tt>: ordered (no nans)</li>
<li><tt>ueq</tt>: unordered or equal</li>
<li><tt>ugt</tt>: unordered or greater than </li>
<li><tt>uge</tt>: unordered or greater than or equal</li>
<li><tt>ult</tt>: unordered or less than </li>
<li><tt>ule</tt>: unordered or less than or equal</li>
<li><tt>une</tt>: unordered or not equal</li>
<li><tt>uno</tt>: unordered (either nans)</li>
<li><tt>true</tt>: no comparison, always returns true</li>
</ol>
<p>The remaining two arguments must be <a href="#t_vector">vector</a> of
<a href="#t_floating">floating point</a> typed. They must also be identical
types.</p>
<h5>Semantics:</h5>
<p>The '<tt>vfcmp</tt>' instruction compares <tt>var1</tt> and <tt>var2</tt>
according to the condition code given as <tt>cond</tt>. The comparison yields a
<a href="#t_vector">vector</a> of <a href="#t_integer">integer</a> result, with
an identical number of elements as the values being compared, and each element
having identical with to the width of the floating point elements. The most
significant bit in each element is 1 if the element-wise comparison evaluates to
true, and is 0 otherwise. All other bits of the result are undefined. The
condition codes are evaluated identically to the
<a href="#i_fcmp">'<tt>fcmp</tt>' instruction</a>.
<h5>Example:</h5>
<pre>
&lt;result&gt; = vfcmp oeq <2 x float> < float 4, float 0 >, < float 5, float 0 > <i>; yields: result=<2 x i32> < i32 0, i32 -1 ></i>
&lt;result&gt; = vfcmp ult <2 x double> < double 1, double 2 >, < double 2, double 2> <i>; yields: result=<2 x i64> < i64 -1, i64 0 ></i>
</pre>
</div>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection"> <a name="i_phi">'<tt>phi</tt>'
Instruction</a> </div>

View File

@ -689,6 +689,8 @@ public:
static Constant *getXor(Constant *C1, Constant *C2);
static Constant *getICmp(unsigned short pred, Constant *LHS, Constant *RHS);
static Constant *getFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
static Constant *getVICmp(unsigned short pred, Constant *LHS, Constant *RHS);
static Constant *getVFCmp(unsigned short pred, Constant *LHS, Constant *RHS);
static Constant *getShl(Constant *C1, Constant *C2);
static Constant *getLShr(Constant *C1, Constant *C2);
static Constant *getAShr(Constant *C1, Constant *C2);

View File

@ -349,6 +349,16 @@ public:
///
static VectorType *get(const Type *ElementType, unsigned NumElements);
/// VectorType::getInteger - This static method gets a VectorType with the
/// same number of elements as the input type, and the element type is an
/// integer type of the same width as the input element type.
///
static VectorType *getInteger(const VectorType *VTy) {
unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
const Type *EltTy = IntegerType::get(EltBits);
return VectorType::get(EltTy, VTy->getNumElements());
}
/// @brief Return the number of elements in the Vector type.
inline unsigned getNumElements() const { return NumElements; }

View File

@ -498,13 +498,55 @@ class CmpInst: public Instruction {
void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
CmpInst(); // do not implement
protected:
CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
const std::string &Name = "", Instruction *InsertBefore = 0);
CmpInst(const Type *ty, 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);
CmpInst(const Type *ty, Instruction::OtherOps op, unsigned short pred,
Value *LHS, Value *RHS, const std::string &Name,
BasicBlock *InsertAtEnd);
public:
/// This enumeration lists the possible predicates for CmpInst subclasses.
/// 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 {
// 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,
BAD_FCMP_PREDICATE = FCMP_TRUE + 1,
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,
BAD_ICMP_PREDICATE = ICMP_SLE + 1
};
// allocate space for exactly two operands
void *operator new(size_t s) {
return User::operator new(s, 2);
@ -576,7 +618,9 @@ public:
static inline bool classof(const CmpInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::ICmp ||
I->getOpcode() == Instruction::FCmp;
I->getOpcode() == Instruction::FCmp ||
I->getOpcode() == Instruction::VICmp ||
I->getOpcode() == Instruction::VFCmp;
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));

View File

@ -166,7 +166,10 @@ HANDLE_OTHER_INST(49, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(50, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
HANDLE_OTHER_INST(51, GetResult, GetResultInst) // Extract individual value
//from aggregate result
LAST_OTHER_INST(51)
HANDLE_OTHER_INST(52, VICmp , VICmpInst ) // Vec Int comparison instruction.
HANDLE_OTHER_INST(53, VFCmp , VFCmpInst ) // Vec FP point comparison instr.
LAST_OTHER_INST(53)
#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST

View File

@ -610,31 +610,11 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value)
//===----------------------------------------------------------------------===//
/// 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.
/// to the constructor. It only operates on integers or pointers. The operands
/// must be identical types.
/// @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,
BAD_ICMP_PREDICATE = ICMP_SLE + 1
};
/// @brief Constructor with insert-before-instruction semantics.
ICmpInst(
Predicate pred, ///< The predicate to use for the comparison
@ -642,7 +622,18 @@ public:
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) {
) : CmpInst(Type::Int1Ty, Instruction::ICmp, pred, LHS, RHS, Name,
InsertBefore) {
assert(pred >= CmpInst::FIRST_ICMP_PREDICATE &&
pred <= CmpInst::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->isInteger() || isa<PointerType>(Op0Ty)) &&
"Invalid operand types for ICmp instruction");
}
/// @brief Constructor with insert-at-block-end semantics.
@ -652,7 +643,18 @@ public:
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) {
) : CmpInst(Type::Int1Ty, Instruction::ICmp, pred, LHS, RHS, Name,
InsertAtEnd) {
assert(pred >= CmpInst::FIRST_ICMP_PREDICATE &&
pred <= CmpInst::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->isInteger() || isa<PointerType>(Op0Ty)) &&
"Invalid operand types for ICmp instruction");
}
/// @brief Return the predicate for this instruction.
@ -783,31 +785,6 @@ public:
/// @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,
BAD_FCMP_PREDICATE = FCMP_TRUE + 1
};
/// @brief Constructor with insert-before-instruction semantics.
FCmpInst(
Predicate pred, ///< The predicate to use for the comparison
@ -815,7 +792,17 @@ public:
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) {
) : CmpInst(Type::Int1Ty, Instruction::FCmp, pred, LHS, RHS, Name,
InsertBefore) {
assert(pred <= 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() &&
"Invalid operand types for FCmp instruction");
}
/// @brief Constructor with insert-at-block-end semantics.
@ -825,7 +812,17 @@ public:
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) {
) : CmpInst(Type::Int1Ty, Instruction::FCmp, pred, LHS, RHS, Name,
InsertAtEnd) {
assert(pred <= 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() &&
"Invalid operand types for FCmp instruction");
}
/// @brief Return the predicate for this instruction.
@ -897,6 +894,100 @@ public:
}
};
//===----------------------------------------------------------------------===//
// VICmpInst Class
//===----------------------------------------------------------------------===//
/// This instruction compares its operands according to the predicate given
/// to the constructor. It only operates on vectors of integers.
/// The operands must be identical types.
/// @brief Represents a vector integer comparison operator.
class VICmpInst: public CmpInst {
public:
/// @brief Constructor with insert-before-instruction semantics.
VICmpInst(
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(LHS->getType(), Instruction::VICmp, pred, LHS, RHS, Name,
InsertBefore) {
}
/// @brief Constructor with insert-at-block-end semantics.
VICmpInst(
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(LHS->getType(), Instruction::VICmp, pred, LHS, RHS, Name,
InsertAtEnd) {
}
/// @brief Return the predicate for this instruction.
Predicate getPredicate() const { return Predicate(SubclassData); }
virtual VICmpInst *clone() const;
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const VICmpInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::VICmp;
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
//===----------------------------------------------------------------------===//
// VFCmpInst Class
//===----------------------------------------------------------------------===//
/// This instruction compares its operands according to the predicate given
/// to the constructor. It only operates on vectors of floating point values.
/// The operands must be identical types.
/// @brief Represents a vector floating point comparison operator.
class VFCmpInst: public CmpInst {
public:
/// @brief Constructor with insert-before-instruction semantics.
VFCmpInst(
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(VectorType::getInteger(cast<VectorType>(LHS->getType())),
Instruction::VFCmp, pred, LHS, RHS, Name, InsertBefore) {
}
/// @brief Constructor with insert-at-block-end semantics.
VFCmpInst(
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(VectorType::getInteger(cast<VectorType>(LHS->getType())),
Instruction::VFCmp, pred, LHS, RHS, Name, InsertAtEnd) {
}
/// @brief Return the predicate for this instruction.
Predicate getPredicate() const { return Predicate(SubclassData); }
virtual VFCmpInst *clone() const;
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const VFCmpInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::VFCmp;
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
//===----------------------------------------------------------------------===//
// CallInst Class
//===----------------------------------------------------------------------===//
@ -1908,8 +1999,6 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(SwitchInst, Value)
// InvokeInst Class
//===----------------------------------------------------------------------===//
//===---------------------------------------------------------------------------
/// InvokeInst - Invoke instruction. The SubclassData field is used to hold the
/// calling convention of the call.
///

View File

@ -169,6 +169,8 @@ public:
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
RetTy visitVICmpInst(VICmpInst &I) { DELEGATE(CmpInst);}
RetTy visitVFCmpInst(VFCmpInst &I) { DELEGATE(CmpInst);}
RetTy visitMallocInst(MallocInst &I) { DELEGATE(AllocationInst);}
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(AllocationInst);}
RetTy visitFreeInst(FreeInst &I) { DELEGATE(Instruction); }

View File

@ -566,6 +566,8 @@ int LLLexer::LexIdentifier() {
INSTKEYWORD("xor", BinaryOpVal, Xor, XOR);
INSTKEYWORD("icmp", OtherOpVal, ICmp, ICMP);
INSTKEYWORD("fcmp", OtherOpVal, FCmp, FCMP);
INSTKEYWORD("vicmp", OtherOpVal, VICmp, VICMP);
INSTKEYWORD("vfcmp", OtherOpVal, VFCmp, VFCMP);
INSTKEYWORD("phi", OtherOpVal, PHI, PHI_TOK);
INSTKEYWORD("call", OtherOpVal, Call, CALL);

File diff suppressed because it is too large Load Diff

View File

@ -127,66 +127,68 @@
ASHR = 343,
ICMP = 344,
FCMP = 345,
EQ = 346,
NE = 347,
SLT = 348,
SGT = 349,
SLE = 350,
SGE = 351,
ULT = 352,
UGT = 353,
ULE = 354,
UGE = 355,
OEQ = 356,
ONE = 357,
OLT = 358,
OGT = 359,
OLE = 360,
OGE = 361,
ORD = 362,
UNO = 363,
UEQ = 364,
UNE = 365,
MALLOC = 366,
ALLOCA = 367,
FREE = 368,
LOAD = 369,
STORE = 370,
GETELEMENTPTR = 371,
TRUNC = 372,
ZEXT = 373,
SEXT = 374,
FPTRUNC = 375,
FPEXT = 376,
BITCAST = 377,
UITOFP = 378,
SITOFP = 379,
FPTOUI = 380,
FPTOSI = 381,
INTTOPTR = 382,
PTRTOINT = 383,
PHI_TOK = 384,
SELECT = 385,
VAARG = 386,
EXTRACTELEMENT = 387,
INSERTELEMENT = 388,
SHUFFLEVECTOR = 389,
GETRESULT = 390,
SIGNEXT = 391,
ZEROEXT = 392,
NORETURN = 393,
INREG = 394,
SRET = 395,
NOUNWIND = 396,
NOALIAS = 397,
BYVAL = 398,
NEST = 399,
READNONE = 400,
READONLY = 401,
GC = 402,
DEFAULT = 403,
HIDDEN = 404,
PROTECTED = 405
VICMP = 346,
VFCMP = 347,
EQ = 348,
NE = 349,
SLT = 350,
SGT = 351,
SLE = 352,
SGE = 353,
ULT = 354,
UGT = 355,
ULE = 356,
UGE = 357,
OEQ = 358,
ONE = 359,
OLT = 360,
OGT = 361,
OLE = 362,
OGE = 363,
ORD = 364,
UNO = 365,
UEQ = 366,
UNE = 367,
MALLOC = 368,
ALLOCA = 369,
FREE = 370,
LOAD = 371,
STORE = 372,
GETELEMENTPTR = 373,
TRUNC = 374,
ZEXT = 375,
SEXT = 376,
FPTRUNC = 377,
FPEXT = 378,
BITCAST = 379,
UITOFP = 380,
SITOFP = 381,
FPTOUI = 382,
FPTOSI = 383,
INTTOPTR = 384,
PTRTOINT = 385,
PHI_TOK = 386,
SELECT = 387,
VAARG = 388,
EXTRACTELEMENT = 389,
INSERTELEMENT = 390,
SHUFFLEVECTOR = 391,
GETRESULT = 392,
SIGNEXT = 393,
ZEROEXT = 394,
NORETURN = 395,
INREG = 396,
SRET = 397,
NOUNWIND = 398,
NOALIAS = 399,
BYVAL = 400,
NEST = 401,
READNONE = 402,
READONLY = 403,
GC = 404,
DEFAULT = 405,
HIDDEN = 406,
PROTECTED = 407
};
#endif
/* Tokens. */
@ -278,73 +280,75 @@
#define ASHR 343
#define ICMP 344
#define FCMP 345
#define EQ 346
#define NE 347
#define SLT 348
#define SGT 349
#define SLE 350
#define SGE 351
#define ULT 352
#define UGT 353
#define ULE 354
#define UGE 355
#define OEQ 356
#define ONE 357
#define OLT 358
#define OGT 359
#define OLE 360
#define OGE 361
#define ORD 362
#define UNO 363
#define UEQ 364
#define UNE 365
#define MALLOC 366
#define ALLOCA 367
#define FREE 368
#define LOAD 369
#define STORE 370
#define GETELEMENTPTR 371
#define TRUNC 372
#define ZEXT 373
#define SEXT 374
#define FPTRUNC 375
#define FPEXT 376
#define BITCAST 377
#define UITOFP 378
#define SITOFP 379
#define FPTOUI 380
#define FPTOSI 381
#define INTTOPTR 382
#define PTRTOINT 383
#define PHI_TOK 384
#define SELECT 385
#define VAARG 386
#define EXTRACTELEMENT 387
#define INSERTELEMENT 388
#define SHUFFLEVECTOR 389
#define GETRESULT 390
#define SIGNEXT 391
#define ZEROEXT 392
#define NORETURN 393
#define INREG 394
#define SRET 395
#define NOUNWIND 396
#define NOALIAS 397
#define BYVAL 398
#define NEST 399
#define READNONE 400
#define READONLY 401
#define GC 402
#define DEFAULT 403
#define HIDDEN 404
#define PROTECTED 405
#define VICMP 346
#define VFCMP 347
#define EQ 348
#define NE 349
#define SLT 350
#define SGT 351
#define SLE 352
#define SGE 353
#define ULT 354
#define UGT 355
#define ULE 356
#define UGE 357
#define OEQ 358
#define ONE 359
#define OLT 360
#define OGT 361
#define OLE 362
#define OGE 363
#define ORD 364
#define UNO 365
#define UEQ 366
#define UNE 367
#define MALLOC 368
#define ALLOCA 369
#define FREE 370
#define LOAD 371
#define STORE 372
#define GETELEMENTPTR 373
#define TRUNC 374
#define ZEXT 375
#define SEXT 376
#define FPTRUNC 377
#define FPEXT 378
#define BITCAST 379
#define UITOFP 380
#define SITOFP 381
#define FPTOUI 382
#define FPTOSI 383
#define INTTOPTR 384
#define PTRTOINT 385
#define PHI_TOK 386
#define SELECT 387
#define VAARG 388
#define EXTRACTELEMENT 389
#define INSERTELEMENT 390
#define SHUFFLEVECTOR 391
#define GETRESULT 392
#define SIGNEXT 393
#define ZEROEXT 394
#define NORETURN 395
#define INREG 396
#define SRET 397
#define NOUNWIND 398
#define NOALIAS 399
#define BYVAL 400
#define NEST 401
#define READNONE 402
#define READONLY 403
#define GC 404
#define DEFAULT 405
#define HIDDEN 406
#define PROTECTED 407
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 949 "/Users/sabre/llvm/lib/AsmParser/llvmAsmParser.y"
#line 949 "/llvm/lib/AsmParser/llvmAsmParser.y"
{
llvm::Module *ModuleVal;
llvm::Function *FunctionVal;
@ -392,7 +396,7 @@ typedef union YYSTYPE
llvm::FCmpInst::Predicate FPredicate;
}
/* Line 1529 of yacc.c. */
#line 396 "llvmAsmParser.tab.h"
#line 400 "llvmAsmParser.tab.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1

View File

@ -1075,7 +1075,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
%token <BinaryOpVal> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
%token <BinaryOpVal> SHL LSHR ASHR
%token <OtherOpVal> ICMP FCMP
%token <OtherOpVal> ICMP FCMP VICMP VFCMP
%type <IPredicate> IPredicates
%type <FPredicate> FPredicates
%token EQ NE SLT SGT SLE SGE ULT UGT ULE UGE
@ -1939,6 +1939,16 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
GEN_ERROR("fcmp operand types must match");
$$ = ConstantExpr::getFCmp($2, $4, $6);
}
| VICMP IPredicates '(' ConstVal ',' ConstVal ')' {
if ($4->getType() != $6->getType())
GEN_ERROR("vicmp operand types must match");
$$ = ConstantExpr::getVICmp($2, $4, $6);
}
| VFCMP FPredicates '(' ConstVal ',' ConstVal ')' {
if ($4->getType() != $6->getType())
GEN_ERROR("vfcmp operand types must match");
$$ = ConstantExpr::getVFCmp($2, $4, $6);
}
| EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
if (!ExtractElementInst::isValidOperands($3, $5))
GEN_ERROR("Invalid extractelement operands");
@ -2891,6 +2901,34 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
GEN_ERROR("fcmp operator returned null");
delete $3;
}
| VICMP IPredicates Types ValueRef ',' ValueRef {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
if (!isa<VectorType>((*$3).get()))
GEN_ERROR("Scalar types not supported by vicmp instruction");
Value* tmpVal1 = getVal(*$3, $4);
CHECK_FOR_ERROR
Value* tmpVal2 = getVal(*$3, $6);
CHECK_FOR_ERROR
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
if ($$ == 0)
GEN_ERROR("icmp operator returned null");
delete $3;
}
| VFCMP FPredicates Types ValueRef ',' ValueRef {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
if (!isa<VectorType>((*$3).get()))
GEN_ERROR("Scalar types not supported by vfcmp instruction");
Value* tmpVal1 = getVal(*$3, $4);
CHECK_FOR_ERROR
Value* tmpVal2 = getVal(*$3, $6);
CHECK_FOR_ERROR
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
if ($$ == 0)
GEN_ERROR("fcmp operator returned null");
delete $3;
}
| CastOps ResolvedVal TO Types {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription());

View File

@ -1075,7 +1075,7 @@ Module *llvm::RunVMAsmParser(llvm::MemoryBuffer *MB) {
%token <BinaryOpVal> ADD SUB MUL UDIV SDIV FDIV UREM SREM FREM AND OR XOR
%token <BinaryOpVal> SHL LSHR ASHR
%token <OtherOpVal> ICMP FCMP
%token <OtherOpVal> ICMP FCMP VICMP VFCMP
%type <IPredicate> IPredicates
%type <FPredicate> FPredicates
%token EQ NE SLT SGT SLE SGE ULT UGT ULE UGE
@ -1939,6 +1939,16 @@ ConstExpr: CastOps '(' ConstVal TO Types ')' {
GEN_ERROR("fcmp operand types must match");
$$ = ConstantExpr::getFCmp($2, $4, $6);
}
| VICMP IPredicates '(' ConstVal ',' ConstVal ')' {
if ($4->getType() != $6->getType())
GEN_ERROR("vicmp operand types must match");
$$ = ConstantExpr::getVICmp($2, $4, $6);
}
| VFCMP FPredicates '(' ConstVal ',' ConstVal ')' {
if ($4->getType() != $6->getType())
GEN_ERROR("vfcmp operand types must match");
$$ = ConstantExpr::getVFCmp($2, $4, $6);
}
| EXTRACTELEMENT '(' ConstVal ',' ConstVal ')' {
if (!ExtractElementInst::isValidOperands($3, $5))
GEN_ERROR("Invalid extractelement operands");
@ -2891,6 +2901,34 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
GEN_ERROR("fcmp operator returned null");
delete $3;
}
| VICMP IPredicates Types ValueRef ',' ValueRef {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
if (!isa<VectorType>((*$3).get()))
GEN_ERROR("Scalar types not supported by vicmp instruction");
Value* tmpVal1 = getVal(*$3, $4);
CHECK_FOR_ERROR
Value* tmpVal2 = getVal(*$3, $6);
CHECK_FOR_ERROR
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
if ($$ == 0)
GEN_ERROR("icmp operator returned null");
delete $3;
}
| VFCMP FPredicates Types ValueRef ',' ValueRef {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$3)->getDescription());
if (!isa<VectorType>((*$3).get()))
GEN_ERROR("Scalar types not supported by vfcmp instruction");
Value* tmpVal1 = getVal(*$3, $4);
CHECK_FOR_ERROR
Value* tmpVal2 = getVal(*$3, $6);
CHECK_FOR_ERROR
$$ = CmpInst::create($1, $2, tmpVal1, tmpVal2);
if ($$ == 0)
GEN_ERROR("fcmp operator returned null");
delete $3;
}
| CastOps ResolvedVal TO Types {
if (!UpRefs.empty())
GEN_ERROR("Invalid upreference in type: " + (*$4)->getDescription());

View File

@ -818,8 +818,12 @@ bool BitcodeReader::ParseConstants() {
if (OpTy->isFloatingPoint())
V = ConstantExpr::getFCmp(Record[3], Op0, Op1);
else
else if (OpTy->isInteger())
V = ConstantExpr::getICmp(Record[3], Op0, Op1);
else if (OpTy->isFPOrFPVector())
V = ConstantExpr::getVFCmp(Record[3], Op0, Op1);
else
V = ConstantExpr::getVICmp(Record[3], Op0, Op1);
break;
}
case bitc::CST_CODE_INLINEASM: {
@ -1355,10 +1359,14 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
OpNum+1 != Record.size())
return Error("Invalid CMP record");
if (LHS->getType()->isFPOrFPVector())
I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
else
if (LHS->getType()->isInteger())
I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
else if (LHS->getType()->isFloatingPoint())
I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
else if (LHS->getType()->isFPOrFPVector())
I = new VFCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS);
else
I = new VICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS);
break;
}
case bitc::FUNC_CODE_INST_GETRESULT: { // GETRESULT: [ty, val, n]

View File

@ -635,6 +635,8 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,
break;
case Instruction::ICmp:
case Instruction::FCmp:
case Instruction::VICmp:
case Instruction::VFCmp:
Code = bitc::CST_CODE_CE_CMP;
Record.push_back(VE.getTypeID(C->getOperand(0)->getType()));
Record.push_back(VE.getValueID(C->getOperand(0)));
@ -740,6 +742,8 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
break;
case Instruction::ICmp:
case Instruction::FCmp:
case Instruction::VICmp:
case Instruction::VFCmp:
Code = bitc::FUNC_CODE_INST_CMP;
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
Vals.push_back(VE.getValueID(I.getOperand(1)));

View File

@ -1251,11 +1251,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
Out << I.getOpcodeName();
// Print out the compare instruction predicates
if (const FCmpInst *FCI = dyn_cast<FCmpInst>(&I)) {
Out << " " << getPredicateText(FCI->getPredicate());
} else if (const ICmpInst *ICI = dyn_cast<ICmpInst>(&I)) {
Out << " " << getPredicateText(ICI->getPredicate());
}
if (const CmpInst *CI = dyn_cast<CmpInst>(&I))
Out << " " << getPredicateText(CI->getPredicate());
// Print out the type of the operands...
const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0;

View File

@ -557,9 +557,9 @@ struct VISIBILITY_HIDDEN CompareConstantExpr : public ConstantExpr {
return User::operator new(s, 2);
}
unsigned short predicate;
CompareConstantExpr(Instruction::OtherOps opc, unsigned short pred,
Constant* LHS, Constant* RHS)
: ConstantExpr(Type::Int1Ty, opc, &Op<0>(), 2), predicate(pred) {
CompareConstantExpr(const Type *ty, Instruction::OtherOps opc,
unsigned short pred, Constant* LHS, Constant* RHS)
: ConstantExpr(ty, opc, &Op<0>(), 2), predicate(pred) {
Op<0>().init(LHS, this);
Op<1>().init(RHS, this);
}
@ -690,7 +690,10 @@ Constant *ConstantExpr::getXor(Constant *C1, Constant *C2) {
return get(Instruction::Xor, C1, C2);
}
unsigned ConstantExpr::getPredicate() const {
assert(getOpcode() == Instruction::FCmp || getOpcode() == Instruction::ICmp);
assert(getOpcode() == Instruction::FCmp ||
getOpcode() == Instruction::ICmp ||
getOpcode() == Instruction::VFCmp ||
getOpcode() == Instruction::VICmp);
return ((const CompareConstantExpr*)this)->predicate;
}
Constant *ConstantExpr::getShl(Constant *C1, Constant *C2) {
@ -1564,10 +1567,16 @@ namespace llvm {
// value and it is combined with the instruction opcode by multiplying
// the opcode by one hundred. We must decode this to get the predicate.
if (V.opcode == Instruction::ICmp)
return new CompareConstantExpr(Instruction::ICmp, V.predicate,
return new CompareConstantExpr(Ty, Instruction::ICmp, V.predicate,
V.operands[0], V.operands[1]);
if (V.opcode == Instruction::FCmp)
return new CompareConstantExpr(Instruction::FCmp, V.predicate,
return new CompareConstantExpr(Ty, Instruction::FCmp, V.predicate,
V.operands[0], V.operands[1]);
if (V.opcode == Instruction::VICmp)
return new CompareConstantExpr(Ty, Instruction::VICmp, V.predicate,
V.operands[0], V.operands[1]);
if (V.opcode == Instruction::VFCmp)
return new CompareConstantExpr(Ty, Instruction::VFCmp, V.predicate,
V.operands[0], V.operands[1]);
assert(0 && "Invalid ConstantExpr!");
return 0;
@ -2029,6 +2038,79 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
return ExprConstants->getOrCreate(Type::Int1Ty, Key);
}
Constant *
ConstantExpr::getVICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
assert(isa<VectorType>(LHS->getType()) &&
"Tried to create vicmp operation on non-vector type!");
assert(LHS->getType() == RHS->getType());
assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE &&
pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid VICmp Predicate");
const Type *VTy = cast<VectorType>(LHS->getType());
const Type *EltTy = VTy->getElementType();
unsigned NumElts = VTy->getNumElements();
SmallVector<Constant *, 8> Elts;
for (unsigned i = 0; i != NumElts; ++i) {
Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i),
RHS->getOperand(i));
if (FC) {
uint64_t Val = cast<ConstantInt>(FC)->getZExtValue();
if (Val != 0ULL)
Elts.push_back(ConstantInt::getAllOnesValue(EltTy));
else
Elts.push_back(ConstantInt::get(EltTy, 0ULL));
}
}
if (Elts.size() == NumElts)
return ConstantVector::get(&Elts[0], Elts.size());
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec;
ArgVec.push_back(LHS);
ArgVec.push_back(RHS);
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::VICmp, ArgVec, pred);
return ExprConstants->getOrCreate(LHS->getType(), Key);
}
Constant *
ConstantExpr::getVFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
assert(isa<VectorType>(LHS->getType()) &&
"Tried to create vfcmp operation on non-vector type!");
assert(LHS->getType() == RHS->getType());
assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid VFCmp Predicate");
const VectorType *VTy = cast<VectorType>(LHS->getType());
unsigned NumElts = VTy->getNumElements();
const Type *EltTy = VTy->getElementType();
const Type *REltTy = IntegerType::get(EltTy->getPrimitiveSizeInBits());
const Type *ResultTy = VectorType::get(REltTy, NumElts);
SmallVector<Constant *, 8> Elts;
for (unsigned i = 0; i != NumElts; ++i) {
Constant *FC = ConstantFoldCompareInstruction(pred, LHS->getOperand(i),
RHS->getOperand(i));
if (FC) {
uint64_t Val = cast<ConstantInt>(FC)->getZExtValue();
if (Val != 0ULL)
Elts.push_back(ConstantInt::getAllOnesValue(REltTy));
else
Elts.push_back(ConstantInt::get(REltTy, 0ULL));
}
}
if (Elts.size() == NumElts)
return ConstantVector::get(&Elts[0], Elts.size());
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec;
ArgVec.push_back(LHS);
ArgVec.push_back(RHS);
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::VFCmp, ArgVec, pred);
return ExprConstants->getOrCreate(ResultTy, Key);
}
Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
Constant *Idx) {
if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))

View File

@ -128,6 +128,8 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
// Other instructions...
case ICmp: return "icmp";
case FCmp: return "fcmp";
case VICmp: return "vicmp";
case VFCmp: return "vfcmp";
case PHI: return "phi";
case Select: return "select";
case Call: return "call";

View File

@ -2332,9 +2332,10 @@ BitCastInst::BitCastInst(
// CmpInst Classes
//===----------------------------------------------------------------------===//
CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
const std::string &Name, Instruction *InsertBefore)
: Instruction(Type::Int1Ty, op,
CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate,
Value *LHS, Value *RHS, const std::string &Name,
Instruction *InsertBefore)
: Instruction(ty, op,
OperandTraits<CmpInst>::op_begin(this),
OperandTraits<CmpInst>::operands(this),
InsertBefore) {
@ -2342,34 +2343,12 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
Op<1>().init(RHS, this);
SubclassData = predicate;
setName(Name);
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->isInteger() || isa<PointerType>(Op0Ty)) &&
"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() &&
"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::Int1Ty, op,
CmpInst::CmpInst(const Type *ty, OtherOps op, unsigned short predicate,
Value *LHS, Value *RHS, const std::string &Name,
BasicBlock *InsertAtEnd)
: Instruction(ty, op,
OperandTraits<CmpInst>::op_begin(this),
OperandTraits<CmpInst>::operands(this),
InsertAtEnd) {
@ -2377,52 +2356,44 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
Op<1>().init(RHS, this);
SubclassData = predicate;
setName(Name);
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->isInteger() || isa<PointerType>(Op0Ty)) &&
"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() &&
"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,
return new ICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
InsertBefore);
}
return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name,
InsertBefore);
if (Op == Instruction::FCmp) {
return new FCmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
InsertBefore);
}
if (Op == Instruction::VICmp) {
return new VICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
InsertBefore);
}
return new VFCmpInst(CmpInst::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,
return new ICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
InsertAtEnd);
}
return new FCmpInst(FCmpInst::Predicate(predicate), S1, S2, Name,
InsertAtEnd);
if (Op == Instruction::FCmp) {
return new FCmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
InsertAtEnd);
}
if (Op == Instruction::VICmp) {
return new VICmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
InsertAtEnd);
}
return new VFCmpInst(CmpInst::Predicate(predicate), S1, S2, Name,
InsertAtEnd);
}
void CmpInst::swapOperands() {
@ -2813,6 +2784,13 @@ ICmpInst* ICmpInst::clone() const {
return new ICmpInst(getPredicate(), Op<0>(), Op<1>());
}
VFCmpInst* VFCmpInst::clone() const {
return new VFCmpInst(getPredicate(), Op<0>(), Op<1>());
}
VICmpInst* VICmpInst::clone() const {
return new VICmpInst(getPredicate(), Op<0>(), Op<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)); }