move select validation logic into a shared place where the select ctor,

verifier, asm parser, etc can share it.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61461 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2008-12-29 00:12:50 +00:00
parent d4f6fe55eb
commit b76ec320dc
3 changed files with 36 additions and 17 deletions

View File

@ -1208,6 +1208,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CallInst, Value)
///
class SelectInst : public Instruction {
void init(Value *C, Value *S1, Value *S2) {
assert(!areInvalidOperands(C, S1, S2) && "Invalid operands for select");
Op<0>() = C;
Op<1>() = S1;
Op<2>() = S2;
@ -1246,6 +1247,10 @@ public:
Value *getCondition() const { return Op<0>(); }
Value *getTrueValue() const { return Op<1>(); }
Value *getFalseValue() const { return Op<2>(); }
/// areInvalidOperands - Return a string if the specified operands are invalid
/// for a select operation, otherwise return null.
static const char *areInvalidOperands(Value *Cond, Value *True, Value *False);
/// Transparently provide more efficient getOperand methods.
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);

View File

@ -138,6 +138,33 @@ TerminatorInst::~TerminatorInst() {
UnaryInstruction::~UnaryInstruction() {
}
//===----------------------------------------------------------------------===//
// SelectInst Class
//===----------------------------------------------------------------------===//
/// areInvalidOperands - Return a string if the specified operands are invalid
/// for a select operation, otherwise return null.
const char *SelectInst::areInvalidOperands(Value *Op0, Value *Op1, Value *Op2) {
if (Op1->getType() != Op2->getType())
return "both values to select must have same type";
if (const VectorType *VT = dyn_cast<VectorType>(Op0->getType())) {
// Vector select.
if (VT->getElementType() != Type::Int1Ty)
return "vector select condition element type must be i1";
const VectorType *ET = dyn_cast<VectorType>(Op1->getType());
if (ET == 0)
return "selected values for vector select must be vectors";
if (ET->getNumElements() != VT->getNumElements())
return "vector select requires selected vectors to have "
"the same vector length as select condition";
} else if (Op0->getType() != Type::Int1Ty) {
return "select condition must be i1 or <n x i1>";
}
return 0;
}
//===----------------------------------------------------------------------===//
// PHINode Class
//===----------------------------------------------------------------------===//

View File

@ -687,23 +687,10 @@ void Verifier::visitSwitchInst(SwitchInst &SI) {
}
void Verifier::visitSelectInst(SelectInst &SI) {
if (const VectorType* vt
= dyn_cast<VectorType>(SI.getCondition()->getType())) {
Assert1( vt->getElementType() == Type::Int1Ty,
"Select condition type must be vector of bool!", &SI);
if (const VectorType* val_vt
= dyn_cast<VectorType>(SI.getTrueValue()->getType())) {
Assert1( vt->getNumElements() == val_vt->getNumElements(),
"Select vector size != value vector size", &SI);
} else {
Assert1(0, "Vector select values must have vector types", &SI);
}
} else {
Assert1(SI.getCondition()->getType() == Type::Int1Ty,
"Select condition type must be bool!", &SI);
}
Assert1(SI.getTrueValue()->getType() == SI.getFalseValue()->getType(),
"Select values must have identical types!", &SI);
Assert1(!SelectInst::areInvalidOperands(SI.getOperand(0), SI.getOperand(1),
SI.getOperand(2)),
"Invalid operands for select instruction!", &SI);
Assert1(SI.getTrueValue()->getType() == SI.getType(),
"Select values must have same type as select instruction!", &SI);
visitInstruction(SI);