reject patterns that mention a name in the destination pattern
authorChris Lattner <sabre@nondot.org>
Tue, 23 Feb 2010 06:35:45 +0000 (06:35 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 23 Feb 2010 06:35:45 +0000 (06:35 +0000)
but not in the input.  Previously, this would trigger an abort
late in the isel logic.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96898 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/CodeGenDAGPatterns.cpp

index c789f3a2e5c56c5a253f233c4f4bd849478003f3..7912040c55603337e2eda98e3f1d8ddb9003e832 100644 (file)
@@ -2078,21 +2078,47 @@ void CodeGenDAGPatterns::ParseInstructions() {
     }
     
     Record *Instr = II->first;
-    TreePatternNode *DstPattern = TheInst.getResultPattern();
     AddPatternToMatch(I,
                       PatternToMatch(Instr->getValueAsListInit("Predicates"),
-                                     SrcPattern, DstPattern,
+                                     SrcPattern,
+                                     TheInst.getResultPattern(),
                                      TheInst.getImpResults(),
                                      Instr->getValueAsInt("AddedComplexity")));
   }
 }
 
+static void FindNames(const TreePatternNode *P, 
+                      std::map<std::string, const TreePatternNode*> &Names) {
+  if (!P->getName().empty())
+    Names[P->getName()] = P;
+  
+  if (!P->isLeaf()) {
+    for (unsigned i = 0, e = P->getNumChildren(); i != e; ++i)
+      FindNames(P->getChild(i), Names);
+  }
+}
+
 void CodeGenDAGPatterns::AddPatternToMatch(const TreePattern *Pattern,
                                            const PatternToMatch &PTM) {
+  // Do some sanity checking on the pattern we're about to match.
   std::string Reason;
   if (!PTM.getSrcPattern()->canPatternMatch(Reason, *this))
-    Pattern->error("Instruction can never match: " + Reason);
+    Pattern->error("Pattern can never match: " + Reason);
   
+  // Find all of the named values in the input and output, ensure they have the
+  // same type.
+  std::map<std::string, const TreePatternNode*> SrcNames, DstNames;
+  FindNames(PTM.getSrcPattern(), SrcNames);
+  FindNames(PTM.getDstPattern(), DstNames);
+
+  // Scan all of the named values in the destination pattern, rejecting them if
+  // they don't exist in the input pattern.
+  for (std::map<std::string, const TreePatternNode*>::iterator
+         I = DstNames.begin(), E = DstNames.end(); I != E; ++I)
+    if (SrcNames[I->first] == 0)
+      Pattern->error("Pattern has input without matching name in output: $" +
+                     I->first);
+
   PatternsToMatch.push_back(PTM);
 }