Index: include/llvm/Analysis/LoopInfo.h =================================================================== --- include/llvm/Analysis/LoopInfo.h +++ include/llvm/Analysis/LoopInfo.h @@ -754,6 +754,28 @@ return true; } + + /// Checks if using a specific instruction can break LCSSA in any loop. + /// + /// Return true if using \p Inst just before \p NewLoc will break LCSSA, + /// assuming that the function containing \p Inst and \p NewLoc is currently + /// in LCSSA form. + bool usePreservesLCSSAForm(Instruction *Inst, Instruction *NewLoc) { + assert(Inst->getFunction() == NewLoc->getFunction() && "Can't reason about IPO!"); + + auto *OldBB = Inst->getParent(); + auto *NewBB = NewLoc->getParent(); + + // Movement within the same loop does not break LCSSA (the equality check is + // to avoid doing a hashtable lookup in case of intra-block movement). + if (OldBB == NewBB) + return true; + + auto *OldLoop = getLoopFor(OldBB); + auto *NewLoop = getLoopFor(NewBB); + + return OldLoop->contains(NewLoop); + } }; // Allow clients to walk the list of nested loops... Index: lib/Analysis/ScalarEvolutionExpander.cpp =================================================================== --- lib/Analysis/ScalarEvolutionExpander.cpp +++ lib/Analysis/ScalarEvolutionExpander.cpp @@ -1655,7 +1655,8 @@ for (auto const &Ent : *Set) { if (Ent && isa(Ent) && S->getType() == Ent->getType() && cast(Ent)->getFunction() == InsertPt->getFunction() && - SE.DT.dominates(cast(Ent), InsertPt)) { + SE.DT.dominates(cast(Ent), InsertPt) && + SE.LI.usePreservesLCSSAForm(cast(Ent), InsertPt)) { V = Ent; break; }