diff options
author | Chris Lattner <sabre@nondot.org> | 2010-02-23 06:35:45 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-02-23 06:35:45 +0000 |
commit | 94d3b0a77d222e340afe727e2dacad4bd1424929 (patch) | |
tree | 2a50e7c13cca6b915e1e09f3fe1056b4fc449dc9 /llvm/utils/TableGen/CodeGenDAGPatterns.cpp | |
parent | 8939e400b64f8b1a125a386e5ce08e8c3e28775a (diff) | |
download | bcm5719-llvm-94d3b0a77d222e340afe727e2dacad4bd1424929.tar.gz bcm5719-llvm-94d3b0a77d222e340afe727e2dacad4bd1424929.zip |
reject patterns that mention a name in the destination pattern
but not in the input. Previously, this would trigger an abort
late in the isel logic.
llvm-svn: 96898
Diffstat (limited to 'llvm/utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r-- | llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index c789f3a2e5c..7912040c556 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -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); } |