/// 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!
--- /dev/null
+; RUN: llvm-as < %s | llc -march=x86 >/dev/null
+; PR4699
+
+; Handle this extractvalue-of-extractvalue case without getting in
+; trouble with CSE in DAGCombine.
+
+ %cc = type { %crd }
+ %cr = type { i32 }
+ %crd = type { i64, %cr* }
+ %pp = type { %cc }
+
+define fastcc void @foo(%pp* nocapture byval %p_arg) {
+entry:
+ %tmp2 = getelementptr %pp* %p_arg, i64 0, i32 0 ; <%cc*> [#uses=
+ %tmp3 = load %cc* %tmp2 ; <%cc> [#uses=1]
+ %tmp34 = extractvalue %cc %tmp3, 0 ; <%crd> [#uses=1]
+ %tmp345 = extractvalue %crd %tmp34, 0 ; <i64> [#uses=1]
+ %.ptr.i = load %cr** undef ; <%cr*> [#uses=0]
+ %tmp15.i = shl i64 %tmp345, 3 ; <i64> [#uses=0]
+ store %cr* undef, %cr** undef
+ ret void
+}
+
+