From b76ec320dc2d612990139122c01a1945f9d0e654 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 29 Dec 2008 00:12:50 +0000 Subject: [PATCH] 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 --- include/llvm/Instructions.h | 5 +++++ lib/VMCore/Instructions.cpp | 27 +++++++++++++++++++++++++++ lib/VMCore/Verifier.cpp | 21 ++++----------------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index bc4abc9797b..b833c672ba7 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -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); diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 5b271d6a31c..e2ba9b49b05 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -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(Op0->getType())) { + // Vector select. + if (VT->getElementType() != Type::Int1Ty) + return "vector select condition element type must be i1"; + const VectorType *ET = dyn_cast(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 "; + } + return 0; +} + + //===----------------------------------------------------------------------===// // PHINode Class //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 27c640e9175..592077344a6 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -687,23 +687,10 @@ void Verifier::visitSwitchInst(SwitchInst &SI) { } void Verifier::visitSelectInst(SelectInst &SI) { - if (const VectorType* vt - = dyn_cast(SI.getCondition()->getType())) { - Assert1( vt->getElementType() == Type::Int1Ty, - "Select condition type must be vector of bool!", &SI); - if (const VectorType* val_vt - = dyn_cast(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);