diff --git a/include/llvm/Transforms/Utils/LoopUtils.h b/include/llvm/Transforms/Utils/LoopUtils.h index 2171350d565..5864e22e135 100644 --- a/include/llvm/Transforms/Utils/LoopUtils.h +++ b/include/llvm/Transforms/Utils/LoopUtils.h @@ -34,6 +34,19 @@ BasicBlock *InsertPreheaderForLoop(Loop *L, Pass *P); bool simplifyLoop(Loop *L, DominatorTree *DT, LoopInfo *LI, Pass *PP, AliasAnalysis *AA = 0, ScalarEvolution *SE = 0); +/// \brief Put loop into LCSSA form. +/// +/// Looks at all instructions in the loop which have uses outside of the +/// current loop. For each, an LCSSA PHI node is inserted and the uses outside +/// the loop are rewritten to use this node. +/// +/// LoopInfo and DominatorTree are required and preserved. +/// +/// If ScalarEvolution is passed in, it will be preserved. +/// +/// Returns true if any modifications are made to the loop. +bool formLCSSA(Loop &L, DominatorTree &DT, ScalarEvolution *SE = 0); + } #endif diff --git a/lib/Transforms/Scalar/LICM.cpp b/lib/Transforms/Scalar/LICM.cpp index 46d5ca3dcad..e62daa63cd0 100644 --- a/lib/Transforms/Scalar/LICM.cpp +++ b/lib/Transforms/Scalar/LICM.cpp @@ -54,6 +54,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetLibraryInfo.h" #include "llvm/Transforms/Utils/Local.h" +#include "llvm/Transforms/Utils/LoopUtils.h" #include "llvm/Transforms/Utils/SSAUpdater.h" #include using namespace llvm; @@ -85,10 +86,12 @@ namespace { AU.addRequired(); AU.addRequired(); AU.addRequiredID(LoopSimplifyID); + AU.addPreservedID(LoopSimplifyID); + AU.addRequiredID(LCSSAID); + AU.addPreservedID(LCSSAID); AU.addRequired(); AU.addPreserved(); AU.addPreserved(); - AU.addPreservedID(LoopSimplifyID); AU.addRequired(); } @@ -193,6 +196,8 @@ INITIALIZE_PASS_BEGIN(LICM, "licm", "Loop Invariant Code Motion", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(LoopInfo) INITIALIZE_PASS_DEPENDENCY(LoopSimplify) +INITIALIZE_PASS_DEPENDENCY(LCSSA) +INITIALIZE_PASS_DEPENDENCY(ScalarEvolution) INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo) INITIALIZE_AG_DEPENDENCY(AliasAnalysis) INITIALIZE_PASS_END(LICM, "licm", "Loop Invariant Code Motion", false, false) @@ -283,6 +288,14 @@ bool LICM::runOnLoop(Loop *L, LPPassManager &LPM) { PromoteAliasSet(*I, ExitBlocks, InsertPts); } + // If we have successfully changed the loop, re-form LCSSA and also re-form + // LCSSA in the parent loop as hoisting or sinking may have broken it. + if (Changed) { + formLCSSA(*L, *DT, getAnalysisIfAvailable()); + if (Loop *ParentL = L->getParentLoop()) + formLCSSA(*ParentL, *DT, getAnalysisIfAvailable()); + } + // Clear out loops state information for the next iteration CurLoop = 0; Preheader = 0; @@ -451,6 +464,19 @@ bool LICM::canSinkOrHoistInst(Instruction &I) { return isSafeToExecuteUnconditionally(I); } +/// \brief Returns true if a PHINode is a trivially replaceable with an +/// Instruction. +/// +/// This is true when all incoming values are that instruction. This pattern +/// occurs most often with LCSSA PHI nodes. +static bool isTriviallyReplacablePHI(PHINode &PN, Instruction &I) { + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) + if (PN.getIncomingValue(i) != &I) + return false; + + return true; +} + /// isNotUsedInLoop - Return true if the only users of this instruction are /// outside of the loop. If this is true, we can sink the instruction to the /// exit blocks of the loop. @@ -459,18 +485,48 @@ bool LICM::isNotUsedInLoop(Instruction &I) { for (Value::use_iterator UI = I.use_begin(), E = I.use_end(); UI != E; ++UI) { Instruction *User = cast(*UI); if (PHINode *PN = dyn_cast(User)) { - // PHI node uses occur in predecessor blocks! + // A PHI node where all of the incoming values are this instruction are + // special -- they can just be RAUW'ed with the instruction and thus + // don't require a use in the predecessor. This is a particular important + // special case because it is the pattern found in LCSSA form. + if (isTriviallyReplacablePHI(*PN, I)) { + if (CurLoop->contains(PN)) + return false; + else + continue; + } + + // Otherwise, PHI node uses occur in predecessor blocks if the incoming + // values. Check for such a use being inside the loop. for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) if (PN->getIncomingValue(i) == &I) if (CurLoop->contains(PN->getIncomingBlock(i))) return false; - } else if (CurLoop->contains(User)) { - return false; + + continue; } + + if (CurLoop->contains(User)) + return false; } return true; } +static BasicBlock::iterator +replaceTrivialPHIsAndGetInsertionPt(BasicBlock &BB, Instruction &I) { + BasicBlock::iterator II = BB.begin(); + while (PHINode *PN = dyn_cast(II)) { + ++II; + if (isTriviallyReplacablePHI(*PN, I)) { + PN->replaceAllUsesWith(&I); + PN->eraseFromParent(); + } + } + if (isa(II)) + ++II; + + return II; +} /// sink - When an instruction is found to only be used outside of the loop, /// this function moves it to the exit blocks and patches up SSA form as needed. @@ -502,9 +558,14 @@ void LICM::sink(Instruction &I) { I.replaceAllUsesWith(UndefValue::get(I.getType())); I.eraseFromParent(); } else { + // Look for any LCSSA PHI nodes for this instruction in the exit blocks + // and replace them. + BasicBlock::iterator II = + replaceTrivialPHIsAndGetInsertionPt(*ExitBlocks[0], I); + // Move the instruction to the start of the exit block, after any PHI // nodes in it. - I.moveBefore(ExitBlocks[0]->getFirstInsertionPt()); + I.moveBefore(II); // This instruction is no longer in the AST for the current loop, because // we just sunk it out of the loop. If we just sunk it into an outer @@ -546,8 +607,10 @@ void LICM::sink(Instruction &I) { if (!DT->dominates(InstOrigBB, ExitBlock)) continue; - // Insert the code after the last PHI node. - BasicBlock::iterator InsertPt = ExitBlock->getFirstInsertionPt(); + // Look for any LCSSA PHI nodes for this instruction in the exit blocks + // and replace them. Then get the insertion point after the last PHI. + BasicBlock::iterator InsertPt = + replaceTrivialPHIsAndGetInsertionPt(*ExitBlock, I); // If this is the first exit block processed, just move the original // instruction, otherwise clone the original instruction and insert diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp index d87fdf0eafa..546f4b160a5 100644 --- a/lib/Transforms/Utils/LCSSA.cpp +++ b/lib/Transforms/Utils/LCSSA.cpp @@ -39,208 +39,95 @@ #include "llvm/IR/Instructions.h" #include "llvm/Pass.h" #include "llvm/Support/PredIteratorCache.h" +#include "llvm/Transforms/Utils/LoopUtils.h" #include "llvm/Transforms/Utils/SSAUpdater.h" using namespace llvm; STATISTIC(NumLCSSA, "Number of live out of a loop variables"); -namespace { - struct LCSSA : public LoopPass { - static char ID; // Pass identification, replacement for typeid - LCSSA() : LoopPass(ID) { - initializeLCSSAPass(*PassRegistry::getPassRegistry()); - } - - // Cached analysis information for the current function. - DominatorTree *DT; - LoopInfo *LI; - ScalarEvolution *SE; - PredIteratorCache PredCache; - Loop *L; - - virtual bool runOnLoop(Loop *L, LPPassManager &LPM); - - /// This transformation requires natural loop information & requires that - /// loop preheaders be inserted into the CFG. It maintains both of these, - /// as well as the CFG. It also requires dominator information. - /// - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesCFG(); - - AU.addRequired(); - AU.addRequired(); - AU.addPreservedID(LoopSimplifyID); - AU.addPreserved(); - } - private: - bool ProcessInstruction(Instruction *Inst, - const SmallVectorImpl &ExitBlocks); - - /// verifyAnalysis() - Verify loop nest. - virtual void verifyAnalysis() const { - // Check the special guarantees that LCSSA makes. - assert(L->isLCSSAForm(*DT) && "LCSSA form not preserved!"); - } - }; -} - -char LCSSA::ID = 0; -INITIALIZE_PASS_BEGIN(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false) -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) -INITIALIZE_PASS_DEPENDENCY(LoopInfo) -INITIALIZE_PASS_END(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false) - -Pass *llvm::createLCSSAPass() { return new LCSSA(); } -char &llvm::LCSSAID = LCSSA::ID; - - -/// BlockDominatesAnExit - Return true if the specified block dominates at least -/// one of the blocks in the specified list. -static bool BlockDominatesAnExit(BasicBlock *BB, - const SmallVectorImpl &ExitBlocks, - DominatorTree *DT) { - DomTreeNode *DomNode = DT->getNode(BB); - for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) - if (DT->dominates(DomNode, DT->getNode(ExitBlocks[i]))) - return true; - - return false; -} - - -/// runOnFunction - Process all loops in the function, inner-most out. -bool LCSSA::runOnLoop(Loop *TheLoop, LPPassManager &LPM) { - L = TheLoop; - - DT = &getAnalysis().getDomTree(); - LI = &getAnalysis(); - SE = getAnalysisIfAvailable(); - - // Get the set of exiting blocks. - SmallVector ExitBlocks; - L->getExitBlocks(ExitBlocks); - - if (ExitBlocks.empty()) - return false; - - // Look at all the instructions in the loop, checking to see if they have uses - // outside the loop. If so, rewrite those uses. - bool MadeChange = false; - - for (Loop::block_iterator BBI = L->block_begin(), E = L->block_end(); - BBI != E; ++BBI) { - BasicBlock *BB = *BBI; - - // For large loops, avoid use-scanning by using dominance information: In - // particular, if a block does not dominate any of the loop exits, then none - // of the values defined in the block could be used outside the loop. - if (!BlockDominatesAnExit(BB, ExitBlocks, DT)) - continue; - - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); - I != E; ++I) { - // Reject two common cases fast: instructions with no uses (like stores) - // and instructions with one use that is in the same block as this. - if (I->use_empty() || - (I->hasOneUse() && I->use_back()->getParent() == BB && - !isa(I->use_back()))) - continue; - - MadeChange |= ProcessInstruction(I, ExitBlocks); - } - } - - // If we modified the code, remove any caches about the loop from SCEV to - // avoid dangling entries. - // FIXME: This is a big hammer, can we clear the cache more selectively? - if (SE && MadeChange) - SE->forgetLoop(L); - - assert(L->isLCSSAForm(*DT)); - PredCache.clear(); - - return MadeChange; -} - -/// isExitBlock - Return true if the specified block is in the list. +/// Return true if the specified block is in the list. static bool isExitBlock(BasicBlock *BB, - const SmallVectorImpl &ExitBlocks) { + const SmallVectorImpl &ExitBlocks) { for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) if (ExitBlocks[i] == BB) return true; return false; } -/// ProcessInstruction - Given an instruction in the loop, check to see if it -/// has any uses that are outside the current loop. If so, insert LCSSA PHI -/// nodes and rewrite the uses. -bool LCSSA::ProcessInstruction(Instruction *Inst, - const SmallVectorImpl &ExitBlocks) { - SmallVector UsesToRewrite; - - BasicBlock *InstBB = Inst->getParent(); - - for (Value::use_iterator UI = Inst->use_begin(), E = Inst->use_end(); - UI != E; ++UI) { +/// Given an instruction in the loop, check to see if it has any uses that are +/// outside the current loop. If so, insert LCSSA PHI nodes and rewrite the +/// uses. +static bool processInstruction(Loop &L, Instruction &Inst, DominatorTree &DT, + const SmallVectorImpl &ExitBlocks, + PredIteratorCache &PredCache) { + SmallVector UsesToRewrite; + + BasicBlock *InstBB = Inst.getParent(); + + for (Value::use_iterator UI = Inst.use_begin(), E = Inst.use_end(); UI != E; + ++UI) { User *U = *UI; BasicBlock *UserBB = cast(U)->getParent(); if (PHINode *PN = dyn_cast(U)) UserBB = PN->getIncomingBlock(UI); - - if (InstBB != UserBB && !L->contains(UserBB)) + + if (InstBB != UserBB && !L.contains(UserBB)) UsesToRewrite.push_back(&UI.getUse()); } // If there are no uses outside the loop, exit with no change. - if (UsesToRewrite.empty()) return false; - + if (UsesToRewrite.empty()) + return false; + ++NumLCSSA; // We are applying the transformation // Invoke instructions are special in that their result value is not available - // along their unwind edge. The code below tests to see whether DomBB dominates + // along their unwind edge. The code below tests to see whether DomBB + // dominates // the value, so adjust DomBB to the normal destination block, which is // effectively where the value is first usable. - BasicBlock *DomBB = Inst->getParent(); - if (InvokeInst *Inv = dyn_cast(Inst)) + BasicBlock *DomBB = Inst.getParent(); + if (InvokeInst *Inv = dyn_cast(&Inst)) DomBB = Inv->getNormalDest(); - DomTreeNode *DomNode = DT->getNode(DomBB); + DomTreeNode *DomNode = DT.getNode(DomBB); - SmallVector AddedPHIs; + SmallVector AddedPHIs; SSAUpdater SSAUpdate; - SSAUpdate.Initialize(Inst->getType(), Inst->getName()); - + SSAUpdate.Initialize(Inst.getType(), Inst.getName()); + // Insert the LCSSA phi's into all of the exit blocks dominated by the // value, and add them to the Phi's map. - for (SmallVectorImpl::const_iterator BBI = ExitBlocks.begin(), - BBE = ExitBlocks.end(); BBI != BBE; ++BBI) { + for (SmallVectorImpl::const_iterator BBI = ExitBlocks.begin(), + BBE = ExitBlocks.end(); + BBI != BBE; ++BBI) { BasicBlock *ExitBB = *BBI; - if (!DT->dominates(DomNode, DT->getNode(ExitBB))) continue; - + if (!DT.dominates(DomNode, DT.getNode(ExitBB))) + continue; + // If we already inserted something for this BB, don't reprocess it. - if (SSAUpdate.HasValueForBlock(ExitBB)) continue; - - PHINode *PN = PHINode::Create(Inst->getType(), - PredCache.GetNumPreds(ExitBB), - Inst->getName()+".lcssa", - ExitBB->begin()); + if (SSAUpdate.HasValueForBlock(ExitBB)) + continue; + + PHINode *PN = PHINode::Create(Inst.getType(), PredCache.GetNumPreds(ExitBB), + Inst.getName() + ".lcssa", ExitBB->begin()); // Add inputs from inside the loop for this PHI. for (BasicBlock **PI = PredCache.GetPreds(ExitBB); *PI; ++PI) { - PN->addIncoming(Inst, *PI); + PN->addIncoming(&Inst, *PI); // If the exit block has a predecessor not within the loop, arrange for // the incoming value use corresponding to that predecessor to be // rewritten in terms of a different LCSSA PHI. - if (!L->contains(*PI)) + if (!L.contains(*PI)) UsesToRewrite.push_back( - &PN->getOperandUse( - PN->getOperandNumForIncomingValue(PN->getNumIncomingValues()-1))); + &PN->getOperandUse(PN->getOperandNumForIncomingValue( + PN->getNumIncomingValues() - 1))); } AddedPHIs.push_back(PN); - + // Remember that this phi makes the value alive in this block. SSAUpdate.AddAvailableValue(ExitBB, PN); } @@ -257,15 +144,14 @@ bool LCSSA::ProcessInstruction(Instruction *Inst, if (PHINode *PN = dyn_cast(User)) UserBB = PN->getIncomingBlock(*UsesToRewrite[i]); - if (isa(UserBB->begin()) && - isExitBlock(UserBB, ExitBlocks)) { + if (isa(UserBB->begin()) && isExitBlock(UserBB, ExitBlocks)) { // Tell the VHs that the uses changed. This updates SCEV's caches. if (UsesToRewrite[i]->get()->hasValueHandle()) ValueHandleBase::ValueIsRAUWd(*UsesToRewrite[i], UserBB->begin()); UsesToRewrite[i]->set(UserBB->begin()); continue; } - + // Otherwise, do full PHI insertion. SSAUpdate.RewriteUse(*UsesToRewrite[i]); } @@ -275,7 +161,152 @@ bool LCSSA::ProcessInstruction(Instruction *Inst, if (AddedPHIs[i]->use_empty()) AddedPHIs[i]->eraseFromParent(); } - + return true; } +/// Return true if the specified block dominates at least +/// one of the blocks in the specified list. +static bool +blockDominatesAnExit(BasicBlock *BB, + DominatorTree &DT, + const SmallVectorImpl &ExitBlocks) { + DomTreeNode *DomNode = DT.getNode(BB); + for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i) + if (DT.dominates(DomNode, DT.getNode(ExitBlocks[i]))) + return true; + + return false; +} + +bool llvm::formLCSSA(Loop &L, DominatorTree &DT, ScalarEvolution *SE) { + bool Changed = false; + + // Get the set of exiting blocks. + SmallVector ExitBlocks; + L.getExitBlocks(ExitBlocks); + + if (ExitBlocks.empty()) + return false; + + PredIteratorCache PredCache; + + // Look at all the instructions in the loop, checking to see if they have uses + // outside the loop. If so, rewrite those uses. + for (Loop::block_iterator BBI = L.block_begin(), BBE = L.block_end(); + BBI != BBE; ++BBI) { + BasicBlock *BB = *BBI; + + // For large loops, avoid use-scanning by using dominance information: In + // particular, if a block does not dominate any of the loop exits, then none + // of the values defined in the block could be used outside the loop. + if (!blockDominatesAnExit(BB, DT, ExitBlocks)) + continue; + + for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { + // Reject two common cases fast: instructions with no uses (like stores) + // and instructions with one use that is in the same block as this. + if (I->use_empty() || + (I->hasOneUse() && I->use_back()->getParent() == BB && + !isa(I->use_back()))) + continue; + + Changed |= processInstruction(L, *I, DT, ExitBlocks, PredCache); + } + } + + // If we modified the code, remove any caches about the loop from SCEV to + // avoid dangling entries. + // FIXME: This is a big hammer, can we clear the cache more selectively? + if (SE && Changed) + SE->forgetLoop(&L); + + assert(L.isLCSSAForm(DT)); + + return Changed; +} + +namespace { +struct LCSSA : public FunctionPass { + static char ID; // Pass identification, replacement for typeid + LCSSA() : FunctionPass(ID) { + initializeLCSSAPass(*PassRegistry::getPassRegistry()); + } + + // Cached analysis information for the current function. + DominatorTree *DT; + LoopInfo *LI; + ScalarEvolution *SE; + + virtual bool runOnFunction(Function &F); + + /// This transformation requires natural loop information & requires that + /// loop preheaders be inserted into the CFG. It maintains both of these, + /// as well as the CFG. It also requires dominator information. + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.setPreservesCFG(); + + AU.addRequired(); + AU.addRequired(); + AU.addPreservedID(LoopSimplifyID); + AU.addPreserved(); + } + +private: + bool processLoop(Loop &L); + + virtual void verifyAnalysis() const; +}; +} + +char LCSSA::ID = 0; +INITIALIZE_PASS_BEGIN(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false) +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) +INITIALIZE_PASS_DEPENDENCY(LoopInfo) +INITIALIZE_PASS_END(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false) + +Pass *llvm::createLCSSAPass() { return new LCSSA(); } +char &llvm::LCSSAID = LCSSA::ID; + + +/// Process all loops in the function, inner-most out. +bool LCSSA::runOnFunction(Function &F) { + bool Changed = false; + LI = &getAnalysis(); + DT = &getAnalysis().getDomTree(); + SE = getAnalysisIfAvailable(); + + // Simplify each loop nest in the function. + for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) + Changed |= processLoop(**I); + + return Changed; +} + +/// Process a loop nest depth first. +bool LCSSA::processLoop(Loop &L) { + bool Changed = false; + + // Recurse depth-first through inner loops. + for (Loop::iterator LI = L.begin(), LE = L.end(); LI != LE; ++LI) + Changed |= processLoop(**LI); + + Changed |= formLCSSA(L, *DT, SE); + return Changed; +} + +static void verifyLoop(Loop &L, DominatorTree &DT) { + // Recurse depth-first through inner loops. + for (Loop::iterator LI = L.begin(), LE = L.end(); LI != LE; ++LI) + verifyLoop(**LI, DT); + + // Check the special guarantees that LCSSA makes. + //assert(L.isLCSSAForm(DT) && "LCSSA form not preserved!"); +} + +void LCSSA::verifyAnalysis() const { + // Verify each loop nest in the function, assuming LI still points at that + // function's loop info. + for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) + verifyLoop(**I, *DT); +} diff --git a/test/Transforms/LICM/scalar_promote.ll b/test/Transforms/LICM/scalar_promote.ll index 92ef15581ce..d7e7c6e9a31 100644 --- a/test/Transforms/LICM/scalar_promote.ll +++ b/test/Transforms/LICM/scalar_promote.ll @@ -24,7 +24,8 @@ Loop: ; preds = %Loop, %0 Out: ret void ; CHECK: Out: -; CHECK-NEXT: store i32 %x2, i32* @X +; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %x2 +; CHECK-NEXT: store i32 %[[LCSSAPHI]], i32* @X ; CHECK-NEXT: ret void } @@ -48,7 +49,8 @@ Loop: ; preds = %Loop, %0 Exit: ; preds = %Loop ret void ; CHECK: Exit: -; CHECK-NEXT: store i32 %V, i32* getelementptr inbounds (i32* @X, i64 1) +; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %V +; CHECK-NEXT: store i32 %[[LCSSAPHI]], i32* getelementptr inbounds (i32* @X, i64 1) ; CHECK-NEXT: ret void } @@ -142,7 +144,8 @@ Loop: ; preds = %Loop, %0 Out: ret void ; CHECK: Out: -; CHECK-NEXT: store i32 %x2, i32* @X +; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %x2 +; CHECK-NEXT: store i32 %[[LCSSAPHI]], i32* @X ; CHECK-NEXT: ret void } @@ -178,7 +181,8 @@ for.end: ; preds = %for.cond.for.end_cr ; CHECK: for.body.lr.ph: ; CHECK-NEXT: %gi.promoted = load i32* %gi, align 4, !tbaa !0 ; CHECK: for.cond.for.end_crit_edge: -; CHECK-NEXT: store i32 %inc, i32* %gi, align 4, !tbaa !0 +; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %inc +; CHECK-NEXT: store i32 %[[LCSSAPHI]], i32* %gi, align 4, !tbaa !0 } !0 = metadata !{metadata !4, metadata !4, i64 0} diff --git a/test/Transforms/LICM/sinking.ll b/test/Transforms/LICM/sinking.ll index b503f96e42c..02d5b84154e 100644 --- a/test/Transforms/LICM/sinking.ll +++ b/test/Transforms/LICM/sinking.ll @@ -76,7 +76,8 @@ Out: ; preds = %Loop ret i32 %tmp.7 ; CHECK-LABEL: @test4( ; CHECK: Out: -; CHECK-NEXT: mul i32 %N, %N_addr.0.pn +; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn +; CHECK-NEXT: mul i32 %N, %[[LCSSAPHI]] ; CHECK-NEXT: sub i32 %tmp.6, %N ; CHECK-NEXT: ret i32 } @@ -152,12 +153,14 @@ Out2: ; preds = %ContLoop ret i32 %tmp.7 ; CHECK-LABEL: @test7( ; CHECK: Out1: -; CHECK-NEXT: mul i32 %N, %N_addr.0.pn +; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn +; CHECK-NEXT: mul i32 %N, %[[LCSSAPHI]] ; CHECK-NEXT: sub i32 %tmp.6, %N ; CHECK-NEXT: ret ; CHECK: Out2: -; CHECK-NEXT: mul i32 %N, %N_addr.0.pn -; CHECK-NEXT: sub i32 %tmp.6 +; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn +; CHECK-NEXT: mul i32 %N, %[[LCSSAPHI]] +; CHECK-NEXT: sub i32 %tmp.6.le, %N ; CHECK-NEXT: ret } @@ -183,7 +186,8 @@ exit2: ; preds = %Cont ; CHECK: exit1: ; CHECK-NEXT: ret i32 0 ; CHECK: exit2: -; CHECK-NEXT: %V = add i32 %X, 1 +; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %X +; CHECK-NEXT: %V = add i32 %[[LCSSAPHI]], 1 ; CHECK-NEXT: ret i32 %V } @@ -229,7 +233,8 @@ Out: ; preds = %Loop ; CHECK-LABEL: @test10( ; CHECK: Out: -; CHECK-NEXT: %tmp.6 = sdiv i32 %N, %N_addr.0.pn +; CHECK-NEXT: %[[LCSSAPHI:.*]] = phi i32 [ %N_addr.0.pn +; CHECK-NEXT: %tmp.6 = sdiv i32 %N, %[[LCSSAPHI]] ; CHECK-NEXT: ret i32 %tmp.6 } diff --git a/test/Transforms/LoopSimplify/ashr-crash.ll b/test/Transforms/LoopSimplify/ashr-crash.ll index f736eefc9b3..69d1ca69a4a 100644 --- a/test/Transforms/LoopSimplify/ashr-crash.ll +++ b/test/Transforms/LoopSimplify/ashr-crash.ll @@ -23,15 +23,15 @@ target triple = "x86_64-apple-macosx" @b = common global i32 0, align 4 ; Check that the def-use chain that leads to the bad SCEV is still -; there, and part of it is hoisted to the entry block. +; there. ; ; CHECK-LABEL: @foo ; CHECK-LABEL: entry: -; CHECK: %cmp4 ; CHECK-LABEL: for.cond1.preheader: ; CHECK-LABEL: for.body3: -; CHECK: %1 = zext i1 %cmp4 to i32 -; CHECK: %xor = xor i32 %1, 1 +; CHECK: %cmp4 +; CHECK: %conv = zext i1 %cmp4 to i32 +; CHECK: %xor = xor i32 %conv6, 1 define void @foo() { entry: br label %for.cond