diff options
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 11 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/extract-extract.ll | 24 | 
2 files changed, 32 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 42d163f79b1..d4d13884cb0 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 00000000000..1e0ce9a3244 --- /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           ; <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 +} + +  | 

