summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-02-23 06:35:45 +0000
committerChris Lattner <sabre@nondot.org>2010-02-23 06:35:45 +0000
commit967d54ae04d562e0d375bb1dda4289cc58590cfa (patch)
tree15a6bff02ff7b886c37e1a97a3b61746c1e847fb /utils
parent25b6f91c549225ae4fc9855b9c82a46d05dfd4d8 (diff)
downloadllvm-967d54ae04d562e0d375bb1dda4289cc58590cfa.tar.gz
llvm-967d54ae04d562e0d375bb1dda4289cc58590cfa.tar.bz2
llvm-967d54ae04d562e0d375bb1dda4289cc58590cfa.tar.xz
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.cpp32
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);
}