diff options
author | Justin Bogner <mail@justinbogner.com> | 2016-06-03 20:47:40 +0000 |
---|---|---|
committer | Justin Bogner <mail@justinbogner.com> | 2016-06-03 20:47:40 +0000 |
commit | 07bf5349eede1fb207a462d19743cc10135996ca (patch) | |
tree | 15513fba58ea8ff6ba38df1f7c877811bc401c20 /llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | |
parent | 4cafbdd4bda350605e481789267e4b6ff4dd21ad (diff) | |
download | bcm5719-llvm-07bf5349eede1fb207a462d19743cc10135996ca.tar.gz bcm5719-llvm-07bf5349eede1fb207a462d19743cc10135996ca.zip |
Re-apply "SDAG: Update ChainNodesMatched as nodes are deleted"
My first attempt at this had an overly aggressive assert - chain nodes
will only be removed, but we could hit the assert if a non-chain node
was CSE'd (NodeToMatch, for instance).
This reapplies r271706 by reverting r271713 and fixing an assert.
Original message:
Avoid relying on UB by looking into deleted nodes for a marker value.
Instead, update the list of chain nodes as we go.
llvm-svn: 271733
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 359919e14b2..0ae1a95b875 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2163,10 +2163,8 @@ void SelectionDAGISel::UpdateChains( // Replace all the chain results with the final chain we ended up with. for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) { SDNode *ChainNode = ChainNodesMatched[i]; - - // If this node was already deleted, don't look at it. - if (ChainNode->getOpcode() == ISD::DELETED_NODE) - continue; + assert(ChainNode->getOpcode() != ISD::DELETED_NODE && + "Deleted node left in chain"); // Don't replace the results of the root node if we're doing a // MorphNodeTo. @@ -3368,6 +3366,13 @@ void SelectionDAGISel::SelectCodeCommon(SDNode *NodeToMatch, } else { assert(NodeToMatch->getOpcode() != ISD::DELETED_NODE && "NodeToMatch was removed partway through selection"); + SelectionDAG::DAGNodeDeletedListener NDL(*CurDAG, [&](SDNode *N, + SDNode *E) { + auto &Chain = ChainNodesMatched; + assert((!E || llvm::find(Chain, N) == Chain.end()) && + "Chain node replaced during MorphNode"); + Chain.erase(std::remove(Chain.begin(), Chain.end(), N), Chain.end()); + }); Res = MorphNode(NodeToMatch, TargetOpc, VTList, Ops, EmitNodeInfo); } |