Fix 12892.

Dead code elimination during coalescing could cause a virtual register
to be split into connected components. The following rewriting would be
confused about the already joined copies present in the code, but
without a corresponding value number in the live range.

Erase all joined copies instantly when joining intervals such that the
MI and LiveInterval representations are always in sync.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157135 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp
index 8bdad5a..4c2b0bf 100644
--- a/lib/CodeGen/LiveRangeEdit.cpp
+++ b/lib/CodeGen/LiveRangeEdit.cpp
@@ -308,6 +308,10 @@
         TheDelegate->LRE_DidCloneVirtReg(Dups.back()->reg, LI->reg);
     }
     ConEQ.Distribute(&Dups[0], MRI);
+    DEBUG({
+      for (unsigned i = 0; i != NumComp; ++i)
+        dbgs() << '\t' << *Dups[i] << '\n';
+    });
   }
 }
 
diff --git a/lib/CodeGen/RegisterCoalescer.cpp b/lib/CodeGen/RegisterCoalescer.cpp
index 74d0454..ca5d280 100644
--- a/lib/CodeGen/RegisterCoalescer.cpp
+++ b/lib/CodeGen/RegisterCoalescer.cpp
@@ -1081,9 +1081,10 @@
   if (!CP.isPhys() && RegClassInfo.isProperSubClass(CP.getNewRC()))
     InflateRegs.push_back(CP.getDstReg());
 
-  // Remember to delete the copy instruction.
-  LIS->RemoveMachineInstrFromMaps(CopyMI);
-  CopyMI->eraseFromParent();
+  // CopyMI has been erased by joinIntervals at this point. Remove it from
+  // ErasedInstrs since copyCoalesceWorkList() won't add a successful join back
+  // to the work list. This keeps ErasedInstrs from growing needlessly.
+  ErasedInstrs.erase(CopyMI);
 
   // Rewrite all SrcReg operands to DstReg.
   // Also update DstReg operands to include DstIdx if it is set.
@@ -1285,6 +1286,7 @@
   SmallVector<VNInfo*, 16> NewVNInfo;
 
   SmallVector<MachineInstr*, 8> DupCopies;
+  SmallVector<MachineInstr*, 8> DeadCopies;
 
   LiveInterval &LHS = LIS->getOrCreateInterval(CP.getDstReg());
   DEBUG({ dbgs() << "\t\tLHS = "; LHS.print(dbgs(), TRI); dbgs() << "\n"; });
@@ -1313,6 +1315,7 @@
       continue;
 
     LHSValsDefinedFromRHS[VNI] = lr->valno;
+    DeadCopies.push_back(MI);
   }
 
   // Loop over the value numbers of the RHS, seeing if any are defined from
@@ -1339,6 +1342,7 @@
         continue;
 
     RHSValsDefinedFromLHS[VNI] = lr->valno;
+    DeadCopies.push_back(MI);
   }
 
   LHSValNoAssignments.resize(LHS.getNumValNums(), -1);
@@ -1438,6 +1442,17 @@
   if (RHSValNoAssignments.empty())
     RHSValNoAssignments.push_back(-1);
 
+  // Now erase all the redundant copies.
+  for (unsigned i = 0, e = DeadCopies.size(); i != e; ++i) {
+    MachineInstr *MI = DeadCopies[i];
+    DEBUG(dbgs() << "\t\terased:\t" << LIS->getInstructionIndex(MI)
+                 << '\t' << *MI);
+    if (!ErasedInstrs.insert(MI))
+      continue;
+    LIS->RemoveMachineInstrFromMaps(MI);
+    MI->eraseFromParent();
+  }
+
   SmallVector<unsigned, 8> SourceRegisters;
   for (SmallVector<MachineInstr*, 8>::iterator I = DupCopies.begin(),
          E = DupCopies.end(); I != E; ++I) {
@@ -1451,7 +1466,8 @@
     // A = X
     unsigned Src = MI->getOperand(1).getReg();
     SourceRegisters.push_back(Src);
-    ErasedInstrs.insert(MI);
+    if (!ErasedInstrs.insert(MI))
+      continue;
     LIS->RemoveMachineInstrFromMaps(MI);
     MI->eraseFromParent();
   }