summaryrefslogtreecommitdiff
path: root/utils/TableGen/CodeGenDAGPatterns.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/TableGen/CodeGenDAGPatterns.cpp')
-rw-r--r--utils/TableGen/CodeGenDAGPatterns.cpp41
1 files changed, 39 insertions, 2 deletions
diff --git a/utils/TableGen/CodeGenDAGPatterns.cpp b/utils/TableGen/CodeGenDAGPatterns.cpp
index 3df6f74b21..2e4ec67d54 100644
--- a/utils/TableGen/CodeGenDAGPatterns.cpp
+++ b/utils/TableGen/CodeGenDAGPatterns.cpp
@@ -2457,13 +2457,44 @@ private:
};
-static void InferFromPattern(CodeGenInstruction &InstInfo,
+static bool InferFromPattern(CodeGenInstruction &InstInfo,
const InstAnalyzer &PatInfo,
Record *PatDef) {
+ bool Error = false;
+
// Remember where InstInfo got its flags.
if (InstInfo.hasUndefFlags())
InstInfo.InferredFrom = PatDef;
+ // Check explicitly set flags for consistency.
+ if (InstInfo.hasSideEffects != PatInfo.hasSideEffects &&
+ !InstInfo.hasSideEffects_Unset) {
+ // Allow explicitly setting hasSideEffects = 1 on instructions, even when
+ // the pattern has no side effects. That could be useful for div/rem
+ // instructions that may trap.
+ if (!InstInfo.hasSideEffects) {
+ Error = true;
+ PrintError(PatDef->getLoc(), "Pattern doesn't match hasSideEffects = " +
+ Twine(InstInfo.hasSideEffects));
+ }
+ }
+
+ if (InstInfo.mayStore != PatInfo.mayStore && !InstInfo.mayStore_Unset) {
+ Error = true;
+ PrintError(PatDef->getLoc(), "Pattern doesn't match mayStore = " +
+ Twine(InstInfo.mayStore));
+ }
+
+ if (InstInfo.mayLoad != PatInfo.mayLoad && !InstInfo.mayLoad_Unset) {
+ // Allow explicitly setting mayLoad = 1, even when the pattern has no loads.
+ // Some targets translate imediates to loads.
+ if (!InstInfo.mayLoad) {
+ Error = true;
+ PrintError(PatDef->getLoc(), "Pattern doesn't match mayLoad = " +
+ Twine(InstInfo.mayLoad));
+ }
+ }
+
// Transfer inferred flags.
InstInfo.hasSideEffects |= PatInfo.hasSideEffects;
InstInfo.mayStore |= PatInfo.mayStore;
@@ -2472,6 +2503,8 @@ static void InferFromPattern(CodeGenInstruction &InstInfo,
// These flags are silently added without any verification.
InstInfo.isBitcast |= PatInfo.isBitcast;
InstInfo.Operands.isVariadic |= PatInfo.isVariadic;
+
+ return Error;
}
/// hasNullFragReference - Return true if the DAG has any reference to the
@@ -2809,6 +2842,7 @@ void CodeGenDAGPatterns::InferInstructionFlags() {
// First try to infer flags from the primary instruction pattern, if any.
SmallVector<CodeGenInstruction*, 8> Revisit;
+ unsigned Errors = 0;
for (unsigned i = 0, e = Instructions.size(); i != e; ++i) {
CodeGenInstruction &InstInfo =
const_cast<CodeGenInstruction &>(*Instructions[i]);
@@ -2829,9 +2863,12 @@ void CodeGenDAGPatterns::InferInstructionFlags() {
}
InstAnalyzer PatInfo(*this);
PatInfo.Analyze(Pattern);
- InferFromPattern(InstInfo, PatInfo, InstInfo.TheDef);
+ Errors += InferFromPattern(InstInfo, PatInfo, InstInfo.TheDef);
}
+ if (Errors)
+ throw "pattern conflicts";
+
// Revisit instructions with undefined flags and no pattern.
if (Target.guessInstructionProperties()) {
for (unsigned i = 0, e = Revisit.size(); i != e; ++i) {