Allow patterns to refer to physical registers that belong to multiple
register classes.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28323 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp
index de36eb0..6916225 100644
--- a/utils/TableGen/CodeGenTarget.cpp
+++ b/utils/TableGen/CodeGenTarget.cpp
@@ -163,6 +163,23 @@
   RegisterClasses.assign(RegClasses.begin(), RegClasses.end());
 }
 
+std::vector<unsigned char> CodeGenTarget::getRegisterVTs(Record *R) const {
+  std::vector<unsigned char> Result;
+  const std::vector<CodeGenRegisterClass> &RCs = getRegisterClasses();
+  for (unsigned i = 0, e = RCs.size(); i != e; ++i) {
+    const CodeGenRegisterClass &RC = RegisterClasses[i];
+    for (unsigned ei = 0, ee = RC.Elements.size(); ei != ee; ++ei) {
+      if (R == RC.Elements[ei]) {
+        const std::vector<MVT::ValueType> &InVTs = RC.getValueTypes();
+        for (unsigned i = 0, e = InVTs.size(); i != e; ++i)
+          Result.push_back(InVTs[i]);
+      }
+    }
+  }
+  return Result;
+}
+
+
 CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) {
   // Rename anonymous register classes.
   if (R->getName().size() > 9 && R->getName()[9] == '.') {
diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h
index bedf1bb..5ed266f 100644
--- a/utils/TableGen/CodeGenTarget.h
+++ b/utils/TableGen/CodeGenTarget.h
@@ -110,6 +110,10 @@
     }
     return FoundRC;
   }
+
+  /// getRegisterVTs - Find the union of all possible ValueTypes for the
+  /// specified physical register.
+  std::vector<unsigned char> getRegisterVTs(Record *R) const;
   
   const std::vector<MVT::ValueType> &getLegalValueTypes() const {
     if (LegalValueTypes.empty()) ReadLegalValueTypes();
diff --git a/utils/TableGen/DAGISelEmitter.cpp b/utils/TableGen/DAGISelEmitter.cpp
index fdf5840..58f217e 100644
--- a/utils/TableGen/DAGISelEmitter.cpp
+++ b/utils/TableGen/DAGISelEmitter.cpp
@@ -565,12 +565,8 @@
   } else if (R->isSubClassOf("Register")) {
     if (NotRegisters) 
       return Unknown;
-    // If the register appears in exactly one regclass, and the regclass has one
-    // value type, use it as the known type.
     const CodeGenTarget &T = TP.getDAGISelEmitter().getTargetInfo();
-    if (const CodeGenRegisterClass *RC = T.getRegisterClassForRegister(R))
-      return ConvertVTs(RC->getValueTypes());
-    return Unknown;
+    return T.getRegisterVTs(R);
   } else if (R->isSubClassOf("ValueType") || R->isSubClassOf("CondCode")) {
     // Using a VTSDNode or CondCodeSDNode.
     return Other;
@@ -607,7 +603,10 @@
         // At some point, it may make sense for this tree pattern to have
         // multiple types.  Assert here that it does not, so we revisit this
         // code when appropriate.
-        assert(getExtTypes().size() == 1 && "TreePattern has too many types!");
+        assert(getExtTypes().size() >= 1 && "TreePattern does not have a type!");
+        MVT::ValueType VT = getTypeNum(0);
+        for (unsigned i = 1, e = getExtTypes().size(); i != e; ++i)
+          assert(getTypeNum(i) == VT && "TreePattern has too many types!");
         
         unsigned Size = MVT::getSizeInBits(getTypeNum(0));
         // Make sure that the value is representable for this type.