move select validation logic into a shared place where the select ctor,
authorChris Lattner <sabre@nondot.org>
Mon, 29 Dec 2008 00:12:50 +0000 (00:12 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 29 Dec 2008 00:12:50 +0000 (00:12 +0000)
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
lib/VMCore/Instructions.cpp
lib/VMCore/Verifier.cpp

index bc4abc9797bf90c404a2316826e06d13616e644a..b833c672ba7eae494bd4453bf5592417c96b1d60 100644 (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);
index 5b271d6a31c354e63f3cdfcd02d9d24584e1589d..e2ba9b49b0533aa4b8e8cd29b41699de85d431a4 100644 (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
 //===----------------------------------------------------------------------===//
index 27c640e9175d77acd7f9c1d5da07bb6451a5dbe9..592077344a6dac958fe1e10461beb159dae078bb 100644 (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);