aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-08-10 23:43:19 +0000
committerDan Gohman <gohman@apple.com>2009-08-10 23:43:19 +0000
commitd546ef7f4201acea72797d80d21f50451646c589 (patch)
treefd3bdbf3b6f17cfd872ba70406d8833230946c15 /lib/CodeGen
parent3f20cb6d9679205620a4fd51d3ec9aa73bf3a508 (diff)
downloadexternal_llvm-d546ef7f4201acea72797d80d21f50451646c589.zip
external_llvm-d546ef7f4201acea72797d80d21f50451646c589.tar.gz
external_llvm-d546ef7f4201acea72797d80d21f50451646c589.tar.bz2
Fix a bug in the DAGCombiner's handling of multiple linked
MERGE_VALUES nodes. Replacing the result values with the operands in one MERGE_VALUES node may cause another MERGE_VALUES node be CSE'd with the first one, and bring its uses along, so that the first one isn't dead, as this code expects. Fix this by iterating until the node is really dead. This fixes PR4699. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78619 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp11
1 files changed, 8 insertions, 3 deletions
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 42d163f..d4d1388 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -924,9 +924,14 @@ SDValue DAGCombiner::visitTokenFactor(SDNode *N) {
/// MERGE_VALUES can always be eliminated.
SDValue DAGCombiner::visitMERGE_VALUES(SDNode *N) {
WorkListRemover DeadNodes(*this);
- for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
- DAG.ReplaceAllUsesOfValueWith(SDValue(N, i), N->getOperand(i),
- &DeadNodes);
+ // Replacing results may cause a different MERGE_VALUES to suddenly
+ // be CSE'd with N, and carry its uses with it. Iterate until no
+ // uses remain, to ensure that the node can be safely deleted.
+ do {
+ for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+ DAG.ReplaceAllUsesOfValueWith(SDValue(N, i), N->getOperand(i),
+ &DeadNodes);
+ } while (!N->use_empty());
removeFromWorkList(N);
DAG.DeleteNode(N);
return SDValue(N, 0); // Return N so it doesn't get rechecked!