From 967d54ae04d562e0d375bb1dda4289cc58590cfa Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 23 Feb 2010 06:35:45 +0000 Subject: [PATCH] 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 --- utils/TableGen/CodeGenDAGPatterns.cpp | 32 ++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp index c789f3a2e5c..7912040c556 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 &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 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::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); } -- 2.34.1