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 | 967d54ae04d562e0d375bb1dda4289cc58590cfa (patch) | |
tree | 15a6bff02ff7b886c37e1a97a3b61746c1e847fb /utils | |
parent | 25b6f91c549225ae4fc9855b9c82a46d05dfd4d8 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96898 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/CodeGenDAGPatterns.cpp | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index c789f3a2e5..7912040c55 100644 --- a/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/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); } |