From 95c5f05641e0afdfcbeb430090e1cd0356dddfbc Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Tue, 3 Feb 2009 10:23:33 +0000 Subject: [PATCH] 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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@63632 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeTypes.cpp | 12 ++++---- test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll | 30 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 83712eec737..71176048cb1 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/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 diff --git a/test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll b/test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll new file mode 100644 index 00000000000..5f97ee7a70c --- /dev/null +++ b/test/CodeGen/X86/2009-02-03-AnalyzedTwice.ll @@ -0,0 +1,30 @@ +; RUN: llvm-as < %s | llc -march=x86 +; PR3411 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i386-pc-linux-gnu" +@g_3 = external global i32 ; [#uses=1] + +define void @bar(i64 %p_66) nounwind { +entry: + br i1 false, label %bb, label %bb1 + +bb: ; preds = %entry + unreachable + +bb1: ; preds = %entry + %0 = load i32* @g_3, align 4 ; [#uses=2] + %1 = sext i32 %0 to i64 ; [#uses=1] + %2 = or i64 %1, %p_66 ; [#uses=1] + %3 = shl i64 %2, 0 ; [#uses=1] + %4 = and i64 %3, %p_66 ; [#uses=1] + %5 = icmp eq i64 %4, 1 ; [#uses=1] + %6 = trunc i64 %p_66 to i32 ; [#uses=2] + %7 = or i32 %0, %6 ; [#uses=2] + %8 = sub i32 %7, %6 ; [#uses=1] + %iftmp.0.0 = select i1 %5, i32 %8, i32 %7 ; [#uses=1] + %9 = tail call i32 @foo(i32 %iftmp.0.0) nounwind ; [#uses=0] + ret void +} + +declare i32 @foo(i32)