Improve support for type-generic vector intrinsics by teaching TableGen how
to handle LLVMMatchType intrinsic parameters, and by adding new subclasses
of LLVMMatchType to match vector types with integral elements that are 
either twice as wide or half as wide as the elements of the matched type.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61834 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index c6e94a5..0039a89 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -483,7 +483,17 @@
   for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
     Record *TyEl = TypeList->getElementAsRecord(i);
     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
-    MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
+    MVT::SimpleValueType VT;
+    if (TyEl->isSubClassOf("LLVMMatchType")) {
+      VT = IS.RetVTs[TyEl->getValueAsInt("Number")];
+      // It only makes sense to use the extended and truncated vector element
+      // variants with iAny types; otherwise, if the intrinsic is not
+      // overloaded, all the types can be specified directly.
+      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
+               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+              VT == MVT::iAny) && "Expected iAny type");
+    } else
+      VT = getValueType(TyEl->getValueAsDef("VT"));
     isOverloaded |= VT == MVT::iAny || VT == MVT::fAny || VT == MVT::iPTRAny;
     IS.RetVTs.push_back(VT);
     IS.RetTypeDefs.push_back(TyEl);
@@ -497,7 +507,21 @@
   for (unsigned i = 0, e = TypeList->getSize(); i != e; ++i) {
     Record *TyEl = TypeList->getElementAsRecord(i);
     assert(TyEl->isSubClassOf("LLVMType") && "Expected a type!");
-    MVT::SimpleValueType VT = getValueType(TyEl->getValueAsDef("VT"));
+    MVT::SimpleValueType VT;
+    if (TyEl->isSubClassOf("LLVMMatchType")) {
+      unsigned MatchTy = TyEl->getValueAsInt("Number");
+      if (MatchTy < IS.RetVTs.size())
+        VT = IS.RetVTs[MatchTy];
+      else
+        VT = IS.ParamVTs[MatchTy - IS.RetVTs.size()];
+      // It only makes sense to use the extended and truncated vector element
+      // variants with iAny types; otherwise, if the intrinsic is not
+      // overloaded, all the types can be specified directly.
+      assert(((!TyEl->isSubClassOf("LLVMExtendedElementVectorType") &&
+               !TyEl->isSubClassOf("LLVMTruncatedElementVectorType")) ||
+              VT == MVT::iAny) && "Expected iAny type");
+    } else
+      VT = getValueType(TyEl->getValueAsDef("VT"));
     isOverloaded |= VT == MVT::iAny || VT == MVT::fAny || VT == MVT::iPTRAny;
     IS.ParamVTs.push_back(VT);
     IS.ParamTypeDefs.push_back(TyEl);