From 998f44f859ee37a9dd6a124a24653af3c99fe291 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 18 Apr 2004 17:32:39 +0000 Subject: [PATCH] Be much more careful about how we update instructions outside of the loop using instructions inside of the loop. This should fix the MishaTest failure from last night. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13038 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/LoopUnroll.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/Transforms/Scalar/LoopUnroll.cpp b/lib/Transforms/Scalar/LoopUnroll.cpp index 02cc509cc2f..266afbbe9b3 100644 --- a/lib/Transforms/Scalar/LoopUnroll.cpp +++ b/lib/Transforms/Scalar/LoopUnroll.cpp @@ -210,16 +210,22 @@ bool LoopUnroll::visitLoop(Loop *L) { } // If there was more than one iteration, replace any uses of values computed - // in the loop with values computed during last iteration of the loop. - if (TripCount != 1) - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { - std::vector Users(I->use_begin(), I->use_end()); - for (unsigned i = 0, e = Users.size(); i != e; ++i) { - Instruction *UI = cast(Users[i]); - if (UI->getParent() != BB && UI->getParent() != NewBlock) - UI->replaceUsesOfWith(I, LastValueMap[I]); - } + // in the loop with values computed during the last iteration of the loop. + if (TripCount != 1) { + std::set Users; + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) + Users.insert(I->use_begin(), I->use_end()); + + // We don't want to reprocess entries with PHI nodes in them. For this + // reason, we look at each operand of each user exactly once, performing the + // stubstitution exactly once. + for (std::set::iterator UI = Users.begin(), E = Users.end(); UI != E; + ++UI) { + Instruction *I = cast(*UI); + if (I->getParent() != BB && I->getParent() != NewBlock) + RemapInstruction(I, LastValueMap); } + } // Now that we cloned the block as many times as we needed, stitch the new // code into the original block and delete the temporary block.