summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorCameron Zwarich <zwarich@apple.com>2011-05-19 21:13:30 +0000
committerCameron Zwarich <zwarich@apple.com>2011-05-19 21:13:30 +0000
commit3a2d255ce612760748990b1b1ea131cc777bafea (patch)
treed47f61a74556078fe94bda17ef34ac6ebc2f3283 /utils
parent24a69c7be213b693b58ac752efeb4a86fe744927 (diff)
downloadllvm-3a2d255ce612760748990b1b1ea131cc777bafea.tar.gz
llvm-3a2d255ce612760748990b1b1ea131cc777bafea.tar.bz2
llvm-3a2d255ce612760748990b1b1ea131cc777bafea.tar.xz
Fix PR9947 by placing OPFL_MemRefs on the node using memory operands rather than
the root if there is only one such node. This leaves only 2 verifier failures in the entire test suite when running "make check". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131677 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/DAGISelMatcherGen.cpp62
1 files changed, 48 insertions, 14 deletions
diff --git a/utils/TableGen/DAGISelMatcherGen.cpp b/utils/TableGen/DAGISelMatcherGen.cpp
index 393ac69eb1..402a239ec5 100644
--- a/utils/TableGen/DAGISelMatcherGen.cpp
+++ b/utils/TableGen/DAGISelMatcherGen.cpp
@@ -646,6 +646,35 @@ GetInstPatternNode(const DAGInstruction &Inst, const TreePatternNode *N) {
return InstPatNode;
}
+static bool
+mayInstNodeLoadOrStore(const TreePatternNode *N,
+ const CodeGenDAGPatterns &CGP) {
+ Record *Op = N->getOperator();
+ const CodeGenTarget &CGT = CGP.getTargetInfo();
+ CodeGenInstruction &II = CGT.getInstruction(Op);
+ return II.mayLoad || II.mayStore;
+}
+
+static unsigned
+numNodesThatMayLoadOrStore(const TreePatternNode *N,
+ const CodeGenDAGPatterns &CGP) {
+ if (N->isLeaf())
+ return 0;
+
+ Record *OpRec = N->getOperator();
+ if (!OpRec->isSubClassOf("Instruction"))
+ return 0;
+
+ unsigned Count = 0;
+ if (mayInstNodeLoadOrStore(N, CGP))
+ ++Count;
+
+ for (unsigned i = 0, e = N->getNumChildren(); i != e; ++i)
+ Count += numNodesThatMayLoadOrStore(N->getChild(i), CGP);
+
+ return Count;
+}
+
void MatcherGen::
EmitResultInstructionAsOperand(const TreePatternNode *N,
SmallVectorImpl<unsigned> &OutputOps) {
@@ -772,21 +801,26 @@ EmitResultInstructionAsOperand(const TreePatternNode *N,
(Pattern.getSrcPattern()->NodeHasProperty(SDNPVariadic, CGP)))
NumFixedArityOperands = Pattern.getSrcPattern()->getNumChildren();
- // If this is the root node and any of the nodes matched nodes in the input
- // pattern have MemRefs in them, have the interpreter collect them and plop
- // them onto this node.
- //
- // FIXME3: This is actively incorrect for result patterns where the root of
- // the pattern is not the memory reference and is also incorrect when the
- // result pattern has multiple memory-referencing instructions. For example,
- // in the X86 backend, this pattern causes the memrefs to get attached to the
- // CVTSS2SDrr instead of the MOVSSrm:
+ // If this is the root node and multiple matched nodes in the input pattern
+ // have MemRefs in them, have the interpreter collect them and plop them onto
+ // this node. If there is just one node with MemRefs, leave them on that node
+ // even if it is not the root.
//
- // def : Pat<(extloadf32 addr:$src),
- // (CVTSS2SDrr (MOVSSrm addr:$src))>;
- //
- bool NodeHasMemRefs =
- isRoot && Pattern.getSrcPattern()->TreeHasProperty(SDNPMemOperand, CGP);
+ // FIXME3: This is actively incorrect for result patterns with multiple
+ // memory-referencing instructions.
+ bool PatternHasMemOperands =
+ Pattern.getSrcPattern()->TreeHasProperty(SDNPMemOperand, CGP);
+
+ bool NodeHasMemRefs = false;
+ if (PatternHasMemOperands) {
+ unsigned NumNodesThatLoadOrStore =
+ numNodesThatMayLoadOrStore(Pattern.getDstPattern(), CGP);
+ bool NodeIsUniqueLoadOrStore = mayInstNodeLoadOrStore(N, CGP) &&
+ NumNodesThatLoadOrStore == 1;
+ NodeHasMemRefs =
+ NodeIsUniqueLoadOrStore || (isRoot && (mayInstNodeLoadOrStore(N, CGP) ||
+ NumNodesThatLoadOrStore != 1));
+ }
assert((!ResultVTs.empty() || TreeHasOutGlue || NodeHasChain) &&
"Node has no result");