Add a bunch of calls to RemoveDeadNode in LegalizeDAG, so legalization doesn't get confused by CSE later on.  Fixes PR11318.

Re-commit of r144034, with an extra fix so that RemoveDeadNode doesn't blow up.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144055 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 7425669..9cce6fe 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -285,6 +285,7 @@
       Result = DAG.getStore(Chain, dl, Result, Ptr, ST->getPointerInfo(),
                            ST->isVolatile(), ST->isNonTemporal(), Alignment);
       DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL);
+      DAG.RemoveDeadNode(ST, DUL);
       return;
     }
     // Do a (aligned) store to a stack slot, then copy from the stack slot
@@ -349,6 +350,7 @@
       DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0],
                   Stores.size());
     DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL);
+    DAG.RemoveDeadNode(ST, DUL);
     return;
   }
   assert(ST->getMemoryVT().isInteger() &&
@@ -381,6 +383,7 @@
   SDValue Result =
     DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2);
   DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL);
+  DAG.RemoveDeadNode(ST, DUL);
 }
 
 /// ExpandUnalignedLoad - Expands an unaligned load to 2 half-size loads.
@@ -1144,6 +1147,7 @@
     if (!ST->isTruncatingStore()) {
       if (SDNode *OptStore = OptimizeFloatStore(ST).getNode()) {
         DAG.ReplaceAllUsesWith(ST, OptStore, this);
+        DAG.RemoveDeadNode(ST, this);
         break;
       }
 
@@ -1169,8 +1173,10 @@
           break;
         case TargetLowering::Custom:
           Tmp1 = TLI.LowerOperation(SDValue(Node, 0), DAG);
-          if (Tmp1.getNode())
+          if (Tmp1.getNode()) {
             DAG.ReplaceAllUsesWith(SDValue(Node, 0), Tmp1, this);
+            DAG.RemoveDeadNode(Node, this);
+          }
           break;
         case TargetLowering::Promote: {
           assert(VT.isVector() && "Unknown legal promote case!");
@@ -1181,6 +1187,7 @@
                          ST->getPointerInfo(), isVolatile,
                          isNonTemporal, Alignment);
           DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this);
+          DAG.RemoveDeadNode(Node, this);
           break;
         }
         }
@@ -1203,6 +1210,7 @@
           DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(),
                             NVT, isVolatile, isNonTemporal, Alignment);
         DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this);
+        DAG.RemoveDeadNode(Node, this);
       } else if (StWidth & (StWidth - 1)) {
         // If not storing a power-of-2 number of bits, expand as two stores.
         assert(!StVT.isVector() && "Unsupported truncstore!");
@@ -1258,6 +1266,7 @@
         // The order of the stores doesn't matter.
         SDValue Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi);
         DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this);
+        DAG.RemoveDeadNode(Node, this);
       } else {
         if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() ||
             Tmp2 != ST->getBasePtr())
@@ -1280,6 +1289,7 @@
           DAG.ReplaceAllUsesWith(SDValue(Node, 0),
                                  TLI.LowerOperation(SDValue(Node, 0), DAG),
                                  this);
+          DAG.RemoveDeadNode(Node, this);
           break;
         case TargetLowering::Expand:
           assert(!StVT.isVector() &&
@@ -1292,6 +1302,7 @@
             DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(),
                          isVolatile, isNonTemporal, Alignment);
           DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this);
+          DAG.RemoveDeadNode(Node, this);
           break;
         }
       }
@@ -3361,6 +3372,7 @@
       DAG.getNode(ISD::BUILD_VECTOR, dl, Node->getValueType(0),
                   &Scalars[0], Scalars.size());
     DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this);
+    DAG.RemoveDeadNode(Node, this);
     break;
   }
   case ISD::GLOBAL_OFFSET_TABLE:
@@ -3377,8 +3389,10 @@
   }
 
   // Replace the original node with the legalized result.
-  if (!Results.empty())
+  if (!Results.empty()) {
     DAG.ReplaceAllUsesWith(Node, Results.data(), this);
+    DAG.RemoveDeadNode(Node, this);
+  }
 }
 
 void SelectionDAGLegalize::PromoteNode(SDNode *Node) {
@@ -3512,8 +3526,10 @@
   }
 
   // Replace the original node with the legalized result.
-  if (!Results.empty())
+  if (!Results.empty()) {
     DAG.ReplaceAllUsesWith(Node, Results.data(), this);
+    DAG.RemoveDeadNode(Node, this);
+  }
 }
 
 // SelectionDAG::Legalize - This is the entry point for the file.
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 010a740..b3f94a4 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -564,6 +564,12 @@
 
 void SelectionDAG::RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener){
   SmallVector<SDNode*, 16> DeadNodes(1, N);
+
+  // Create a dummy node that adds a reference to the root node, preventing
+  // it from being deleted.  (This matters if the root is an operand of the
+  // dead node.)
+  HandleSDNode Dummy(getRoot());
+
   RemoveDeadNodes(DeadNodes, UpdateListener);
 }