diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 42d163f79b11..d4d13884cb0c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/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! diff --git a/llvm/test/CodeGen/X86/extract-extract.ll b/llvm/test/CodeGen/X86/extract-extract.ll new file mode 100644 index 000000000000..1e0ce9a32443 --- /dev/null +++ b/llvm/test/CodeGen/X86/extract-extract.ll @@ -0,0 +1,24 @@ +; 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 ; [#uses=1] + %.ptr.i = load %cr** undef ; <%cr*> [#uses=0] + %tmp15.i = shl i64 %tmp345, 3 ; [#uses=0] + store %cr* undef, %cr** undef + ret void +} + +