Fix the xfail I added a couple of patches back. The issue
authorChris Lattner <sabre@nondot.org>
Tue, 2 Mar 2010 07:50:03 +0000 (07:50 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 2 Mar 2010 07:50:03 +0000 (07:50 +0000)
was that we weren't properly handling the case when interior
nodes of a matched pattern become dead after updating chain
and flag uses.  Now we handle this explicitly in
UpdateChainsAndFlags.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97561 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAGISel.h
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
test/CodeGen/X86/vec_shuffle-18.ll

index e9cbb13fa6629da9fd5cdbf71aa96218236bf1e1..af1273c1e062c62c26bce26d7d6c9427402470f6 100644 (file)
@@ -307,6 +307,12 @@ private:
   /// OpcodeOffset - This is a cache used to dispatch efficiently into isel
   /// state machines that start with a OPC_SwitchOpcode node.
   std::vector<unsigned> OpcodeOffset;
+  
+  void UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
+                            const SmallVectorImpl<SDNode*> &ChainNodesMatched,
+                            SDValue InputFlag,const SmallVectorImpl<SDNode*> &F,
+                            bool isMorphNodeTo);
+    
 };
 
 }
index 7e1ce429ef7d29e4dc22289807df806a7a1150b6..68eb4cbcca311522dd86cfbd644374908dc4f22d 100644 (file)
@@ -796,8 +796,11 @@ void SelectionDAGISel::DoInstructionSelection() {
       
       SDNode *ResNode = Select(Node);
       
+      // FIXME: This is pretty gross.  'Select' should be changed to not return
+      // anything at all and this code should be nuked with a tactical strike.
+      
       // If node should not be replaced, continue with the next one.
-      if (ResNode == Node)
+      if (ResNode == Node || Node->getOpcode() == ISD::DELETED_NODE)
         continue;
       // Replace node.
       if (ResNode)
@@ -1532,11 +1535,16 @@ GetVBR(uint64_t Val, const unsigned char *MatcherTable, unsigned &Idx) {
 
 /// UpdateChainsAndFlags - When a match is complete, this method updates uses of
 /// interior flag and chain results to use the new flag and chain results.
-static void UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
-                              const SmallVectorImpl<SDNode*> &ChainNodesMatched,
-                                 SDValue InputFlag,
-                         const SmallVectorImpl<SDNode*> &FlagResultNodesMatched,
-                                 bool isMorphNodeTo, SelectionDAG *CurDAG) {
+void SelectionDAGISel::
+UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
+                     const SmallVectorImpl<SDNode*> &ChainNodesMatched,
+                     SDValue InputFlag,
+                     const SmallVectorImpl<SDNode*> &FlagResultNodesMatched,
+                     bool isMorphNodeTo) {
+  SmallVector<SDNode*, 4> NowDeadNodes;
+  
+  ISelUpdater ISU(ISelPosition);
+
   // Now that all the normal results are replaced, we replace the chain and
   // flag results if present.
   if (!ChainNodesMatched.empty()) {
@@ -1547,6 +1555,10 @@ static void UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
     for (unsigned i = 0, e = ChainNodesMatched.size(); i != e; ++i) {
       SDNode *ChainNode = ChainNodesMatched[i];
       
+      // If this node was already deleted, don't look at it.
+      if (ChainNode->getOpcode() == ISD::DELETED_NODE)
+        continue;
+      
       // Don't replace the results of the root node if we're doing a
       // MorphNodeTo.
       if (ChainNode == NodeToMatch && isMorphNodeTo)
@@ -1556,7 +1568,11 @@ static void UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
       if (ChainVal.getValueType() == MVT::Flag)
         ChainVal = ChainVal.getValue(ChainVal->getNumValues()-2);
       assert(ChainVal.getValueType() == MVT::Other && "Not a chain?");
-      CurDAG->ReplaceAllUsesOfValueWith(ChainVal, InputChain);
+      CurDAG->ReplaceAllUsesOfValueWith(ChainVal, InputChain, &ISU);
+      
+      // If the node became dead, delete it.
+      if (ChainNode->use_empty())
+        NowDeadNodes.push_back(ChainNode);
     }
   }
   
@@ -1566,13 +1582,25 @@ static void UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
     // Handle any interior nodes explicitly marked.
     for (unsigned i = 0, e = FlagResultNodesMatched.size(); i != e; ++i) {
       SDNode *FRN = FlagResultNodesMatched[i];
+      
+      // If this node was already deleted, don't look at it.
+      if (FRN->getOpcode() == ISD::DELETED_NODE)
+        continue;
+      
       assert(FRN->getValueType(FRN->getNumValues()-1) == MVT::Flag &&
              "Doesn't have a flag result");
       CurDAG->ReplaceAllUsesOfValueWith(SDValue(FRN, FRN->getNumValues()-1),
-                                        InputFlag);
+                                        InputFlag, &ISU);
+      
+      // If the node became dead, delete it.
+      if (FRN->use_empty())
+        NowDeadNodes.push_back(FRN);
     }
   }
   
+  if (!NowDeadNodes.empty())
+    CurDAG->RemoveDeadNodes(NowDeadNodes, &ISU);
+  
   DEBUG(errs() << "ISEL: Match complete!\n");
 }
 
@@ -2363,7 +2391,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
       
       // If the node had chain/flag results, update our notion of the current
       // chain and flag.
-      if (VTs.back() == MVT::Flag) {
+      if (EmitNodeInfo & OPFL_FlagOutput) {
         InputFlag = SDValue(Res, VTs.size()-1);
         if (EmitNodeInfo & OPFL_Chain)
           InputChain = SDValue(Res, VTs.size()-2);
@@ -2392,8 +2420,8 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
       if (Opcode == OPC_MorphNodeTo) {
         // Update chain and flag uses.
         UpdateChainsAndFlags(NodeToMatch, InputChain, ChainNodesMatched,
-                             InputFlag, FlagResultNodesMatched, true, CurDAG);
-        return 0;
+                             InputFlag, FlagResultNodesMatched, true);
+        return Res;
       }
       
       continue;
@@ -2452,7 +2480,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
       
       // Update chain and flag uses.
       UpdateChainsAndFlags(NodeToMatch, InputChain, ChainNodesMatched,
-                           InputFlag, FlagResultNodesMatched, false, CurDAG);
+                           InputFlag, FlagResultNodesMatched, false);
       
       assert(NodeToMatch->use_empty() &&
              "Didn't replace all uses of the node?");
index ab69322e309bdc4290f40c43895942f29481cd76..1104a4a8856b717666fdd825addda4bbfd85a0d2 100644 (file)
@@ -1,5 +1,4 @@
 ; RUN: llc < %s -march=x86 -mattr=+sse2 -mtriple=i686-apple-darwin8.8.0 | grep mov | count 7
-; XFAIL: *
 
        %struct.vector4_t = type { <4 x float> }