From a77c5f758cd19319c626404082dade19ebfffe7a Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Tue, 3 Feb 2009 10:23:33 +0000 Subject: Fix PR3411. When replacing values, nodes are analyzed in any old order. Since analyzing a node analyzes its operands also, this can mean that when we pop a node off the list of nodes to be analyzed, it may already have been analyzed. llvm-svn: 63632 --- llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'llvm/lib/CodeGen') diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 83712eec737..71176048cb1 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -651,7 +651,7 @@ namespace { DTL.NoteDeletion(N, E); // In theory the deleted node could also have been scheduled for analysis. - // So add it to the set of nodes which will not be analyzed. + // So remove it from the set of nodes which will be analyzed. NodesToAnalyze.remove(N); // In general nothing needs to be done for E, since it didn't change but @@ -669,6 +669,7 @@ namespace { assert(N->getNodeId() != DAGTypeLegalizer::ReadyToProcess && N->getNodeId() != DAGTypeLegalizer::Processed && "Invalid node ID for RAUW deletion!"); + N->setNodeId(DAGTypeLegalizer::NewNode); NodesToAnalyze.insert(N); } }; @@ -695,12 +696,13 @@ void DAGTypeLegalizer::ReplaceValueWithHelper(SDValue From, SDValue To) { while (!NodesToAnalyze.empty()) { SDNode *N = NodesToAnalyze.back(); NodesToAnalyze.pop_back(); + if (N->getNodeId() != DAGTypeLegalizer::NewNode) + // The node was analyzed while reanalyzing an earlier node - it is safe to + // skip. Note that this is not a morphing node - otherwise it would still + // be marked NewNode. + continue; // Analyze the node's operands and recalculate the node ID. - assert(N->getNodeId() != DAGTypeLegalizer::ReadyToProcess && - N->getNodeId() != DAGTypeLegalizer::Processed && - "Invalid node ID for RAUW analysis!"); - N->setNodeId(NewNode); SDNode *M = AnalyzeNewNode(N); if (M != N) { // The node morphed into a different node. Make everyone use the new node -- cgit v1.2.3