From 22e621908fdb121474f4806f15ec5c0ce2efeb0a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 16 Feb 2010 00:20:08 +0000 Subject: [PATCH] When reusing an existing PHI node in a loop, be even more strict about the requirements. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96301 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ScalarEvolutionExpander.cpp | 50 ++++++++++++++++++------ 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index b026a3bee0a..c2e1f8902f8 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -646,18 +646,46 @@ SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, SE.getEffectiveSCEVType(Normalized->getType())) && SE.getSCEV(PN) == Normalized) if (BasicBlock *LatchBlock = L->getLoopLatch()) { - // Remember this PHI, even in post-inc mode. - InsertedValues.insert(PN); - // Remember the increment. Instruction *IncV = - cast(PN->getIncomingValueForBlock(LatchBlock) - ->stripPointerCasts()); - rememberInstruction(IncV); - // Make sure the increment is where we want it. But don't move it - // down past a potential existing post-inc user. - if (L == IVIncInsertLoop && !SE.DT->dominates(IncV, IVIncInsertPos)) - IncV->moveBefore(IVIncInsertPos); - return PN; + cast(PN->getIncomingValueForBlock(LatchBlock)); + + // Determine if this is a well-behaved chain of instructions leading + // back to the PHI. It probably will be, if we're scanning an inner + // loop already visited by LSR for example, but it wouldn't have + // to be. + do { + if (IncV->getNumOperands() == 0 || isa(IncV)) { + IncV = 0; + break; + } + IncV = dyn_cast(IncV->getOperand(0)); + if (!IncV) + break; + if (IncV->mayHaveSideEffects()) { + IncV = 0; + break; + } + } while (IncV != PN); + + if (IncV) { + // Ok, the add recurrence looks usable. + // Remember this PHI, even in post-inc mode. + InsertedValues.insert(PN); + // Remember the increment. + IncV = cast(PN->getIncomingValueForBlock(LatchBlock)); + rememberInstruction(IncV); + if (L == IVIncInsertLoop) + do { + if (SE.DT->dominates(IncV, IVIncInsertPos)) + break; + // Make sure the increment is where we want it. But don't move it + // down past a potential existing post-inc user. + IncV->moveBefore(IVIncInsertPos); + IVIncInsertPos = IncV; + IncV = cast(IncV->getOperand(0)); + } while (IncV != PN); + return PN; + } } // Save the original insertion point so we can restore it when we're done.