Add a new "SDTCisVec" SDTypeConstraint.  This complements the vAny type.
There have been a few times where I've wanted this but ended up leaving the
operand type unconstrained.  It is easy to add this now and should help
catch errors in the future.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78849 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 29b41a2..efa7fe4 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -95,7 +95,7 @@
 /// vector contains a vector value type.
 bool isExtVectorInVTs(const std::vector<unsigned char> &EVTs) {
   assert(!EVTs.empty() && "Cannot check for vector in empty ExtVT list!");
-  return !(FilterEVTs(EVTs, isVector).empty());
+  return EVTs[0] == isVec || !(FilterEVTs(EVTs, isVector).empty());
 }
 } // end namespace EEVT.
 } // end namespace llvm.
@@ -190,6 +190,8 @@
     ConstraintType = SDTCisInt;
   } else if (R->isSubClassOf("SDTCisFP")) {
     ConstraintType = SDTCisFP;
+  } else if (R->isSubClassOf("SDTCisVec")) {
+    ConstraintType = SDTCisVec;
   } else if (R->isSubClassOf("SDTCisSameAs")) {
     ConstraintType = SDTCisSameAs;
     x.SDTCisSameAs_Info.OtherOperandNum = R->getValueAsInt("OtherOperandNum");
@@ -283,6 +285,16 @@
       return NodeToApply->UpdateNodeType(FPVTs[0], TP);
     return NodeToApply->UpdateNodeType(EEVT::isFP, TP);
   }
+  case SDTCisVec: {
+    // If there is only one vector type supported, this must be it.
+    std::vector<MVT::SimpleValueType> VecVTs =
+      FilterVTs(CGT.getLegalValueTypes(), isVector);
+        
+    // If we found exactly one supported vector type, apply it.
+    if (VecVTs.size() == 1)
+      return NodeToApply->UpdateNodeType(VecVTs[0], TP);
+    return NodeToApply->UpdateNodeType(EEVT::isVec, TP);
+  }
   case SDTCisSameAs: {
     TreePatternNode *OtherNode =
       getOperandNum(x.SDTCisSameAs_Info.OtherOperandNum, N, NumResults);
@@ -502,7 +514,8 @@
     setTypes(FVTs);
     return true;
   }
-  if (ExtVTs[0] == MVT::vAny && EEVT::isExtVectorInVTs(getExtTypes())) {
+  if ((ExtVTs[0] == EEVT::isVec || ExtVTs[0] == MVT::vAny) &&
+      EEVT::isExtVectorInVTs(getExtTypes())) {
     assert(hasTypeSet() && "should be handled above!");
     std::vector<unsigned char> FVTs = FilterEVTs(getExtTypes(), isVector);
     if (getExtTypes() == FVTs)
@@ -511,16 +524,16 @@
     return true;
   }
       
-  // If we know this is an int or fp type, and we are told it is a specific one,
-  // take the advice.
+  // If we know this is an int, FP, or vector type, and we are told it is a
+  // specific one, take the advice.
   //
   // Similarly, we should probably set the type here to the intersection of
-  // {isInt|isFP} and ExtVTs
+  // {isInt|isFP|isVec} and ExtVTs
   if (((getExtTypeNum(0) == EEVT::isInt || getExtTypeNum(0) == MVT::iAny) &&
        EEVT::isExtIntegerInVTs(ExtVTs)) ||
       ((getExtTypeNum(0) == EEVT::isFP || getExtTypeNum(0) == MVT::fAny) &&
        EEVT::isExtFloatingPointInVTs(ExtVTs)) ||
-      (getExtTypeNum(0) == MVT::vAny &&
+      ((getExtTypeNum(0) == EEVT::isVec || getExtTypeNum(0) == MVT::vAny) &&
        EEVT::isExtVectorInVTs(ExtVTs))) {
     setTypes(ExtVTs);
     return true;
@@ -556,6 +569,7 @@
   case MVT::Other: OS << ":Other"; break;
   case EEVT::isInt: OS << ":isInt"; break;
   case EEVT::isFP : OS << ":isFP"; break;
+  case EEVT::isVec: OS << ":isVec"; break;
   case EEVT::isUnknown: ; /*OS << ":?";*/ break;
   case MVT::iPTR:  OS << ":iPTR"; break;
   case MVT::iPTRAny:  OS << ":iPTRAny"; break;