<div dir="ltr"><div dir="ltr"><div dir="ltr">This crashes clang on the attached file. I reverted the change in r347225<div><br></div><div><div>$ clang -O3 -fexperimental-new-pass-manager t.i -w</div><div>Instruction does not dominate all uses!</div><div>  %spec.select = zext i1 %not.tobool to i64</div><div>  %d = getelementptr inbounds [2 x %struct.b], [2 x %struct.b]* %g, i64 0, i64 %spec.select, i32 1</div><div>in function e</div><div>fatal error: error in backend: Broken function found, compilation aborted!</div></div><div><br></div></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Nov 19, 2018 at 12:33 PM John Brawn via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: john.brawn<br>
Date: Mon Nov 19 03:31:24 2018<br>
New Revision: 347190<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=347190&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=347190&view=rev</a><br>
Log:<br>
[LICM] Make LICM able to hoist phis<br>
<br>
The general approach taken is to make note of loop invariant branches, then when<br>
we see something conditional on that branch, such as a phi, we create a copy of<br>
the branch and (empty versions of) its successors and hoist using that.<br>
<br>
This has no impact by itself that I've been able to see, as LICM typically<br>
doesn't see such phis as they will have been converted into selects by the time<br>
LICM is run, but once we start doing phi-to-select conversion later it will be<br>
important.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D52827" rel="noreferrer" target="_blank">https://reviews.llvm.org/D52827</a><br>
<br>
Added:<br>
    llvm/trunk/test/Transforms/LICM/hoist-phi.ll<br>
Modified:<br>
    llvm/trunk/lib/Transforms/Scalar/LICM.cpp<br>
    llvm/trunk/test/Transforms/LoopVectorize/invariant-store-vectorization.ll<br>
<br>
Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=347190&r1=347189&r2=347190&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=347190&r1=347189&r2=347190&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Mon Nov 19 03:31:24 2018<br>
@@ -31,6 +31,7 @@<br>
 //===----------------------------------------------------------------------===//<br>
<br>
 #include "llvm/Transforms/Scalar/LICM.h"<br>
+#include "llvm/ADT/SetOperations.h"<br>
 #include "llvm/ADT/Statistic.h"<br>
 #include "llvm/Analysis/AliasAnalysis.h"<br>
 #include "llvm/Analysis/AliasSetTracker.h"<br>
@@ -41,6 +42,7 @@<br>
 #include "llvm/Analysis/GuardUtils.h"<br>
 #include "llvm/Analysis/Loads.h"<br>
 #include "llvm/Analysis/LoopInfo.h"<br>
+#include "llvm/Analysis/LoopIterator.h"<br>
 #include "llvm/Analysis/LoopPass.h"<br>
 #include "llvm/Analysis/MemoryBuiltins.h"<br>
 #include "llvm/Analysis/MemorySSA.h"<br>
@@ -75,6 +77,8 @@ using namespace llvm;<br>
<br>
 #define DEBUG_TYPE "licm"<br>
<br>
+STATISTIC(NumCreatedBlocks, "Number of blocks created");<br>
+STATISTIC(NumClonedBranches, "Number of branches cloned");<br>
 STATISTIC(NumSunk, "Number of instructions sunk out of loop");<br>
 STATISTIC(NumHoisted, "Number of instructions hoisted out of loop");<br>
 STATISTIC(NumMovedLoads, "Number of load insts hoisted or sunk");<br>
@@ -103,7 +107,7 @@ static bool isNotUsedOrFreeInLoop(const<br>
                                   const LoopSafetyInfo *SafetyInfo,<br>
                                   TargetTransformInfo *TTI, bool &FreeInLoop);<br>
 static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,<br>
-                  ICFLoopSafetyInfo *SafetyInfo,<br>
+                  BasicBlock *Dest, ICFLoopSafetyInfo *SafetyInfo,<br>
                   OptimizationRemarkEmitter *ORE);<br>
 static bool sink(Instruction &I, LoopInfo *LI, DominatorTree *DT,<br>
                  const Loop *CurLoop, ICFLoopSafetyInfo *SafetyInfo,<br>
@@ -437,6 +441,225 @@ bool llvm::sinkRegion(DomTreeNode *N, Al<br>
   return Changed;<br>
 }<br>
<br>
+// This is a helper class for hoistRegion to make it able to hoist control flow<br>
+// in order to be able to hoist phis. The way this works is that we initially<br>
+// start hoisting to the loop preheader, and when we see a loop invariant branch<br>
+// we make note of this. When we then come to hoist an instruction that's<br>
+// conditional on such a branch we duplicate the branch and the relevant control<br>
+// flow, then hoist the instruction into the block corresponding to its original<br>
+// block in the duplicated control flow.<br>
+class ControlFlowHoister {<br>
+private:<br>
+  // Information about the loop we are hoisting from<br>
+  LoopInfo *LI;<br>
+  DominatorTree *DT;<br>
+  Loop *CurLoop;<br>
+<br>
+  // A map of blocks in the loop to the block their instructions will be hoisted<br>
+  // to.<br>
+  DenseMap<BasicBlock *, BasicBlock *> HoistDestinationMap;<br>
+<br>
+  // The branches that we can hoist, mapped to the block that marks a<br>
+  // convergence point of their control flow.<br>
+  DenseMap<BranchInst *, BasicBlock *> HoistableBranches;<br>
+<br>
+public:<br>
+  ControlFlowHoister(LoopInfo *LI, DominatorTree *DT, Loop *CurLoop)<br>
+      : LI(LI), DT(DT), CurLoop(CurLoop) {}<br>
+<br>
+  void registerPossiblyHoistableBranch(BranchInst *BI) {<br>
+    // We can only hoist conditional branches with loop invariant operands.<br>
+    if (!BI->isConditional() || !CurLoop->hasLoopInvariantOperands(BI))<br>
+      return;<br>
+<br>
+    // The branch destinations need to be in the loop, and we don't gain<br>
+    // anything by duplicating conditional branches with duplicate successors,<br>
+    // as it's essentially the same as an unconditional branch.<br>
+    BasicBlock *TrueDest = BI->getSuccessor(0);<br>
+    BasicBlock *FalseDest = BI->getSuccessor(1);<br>
+    if (!CurLoop->contains(TrueDest) || !CurLoop->contains(FalseDest) ||<br>
+        TrueDest == FalseDest)<br>
+      return;<br>
+<br>
+    // We can hoist BI if one branch destination is the successor of the other,<br>
+    // or both have common successor which we check by seeing if the<br>
+    // intersection of their successors is non-empty.<br>
+    // TODO: This could be expanded to allowing branches where both ends<br>
+    // eventually converge to a single block.<br>
+    SmallPtrSet<BasicBlock *, 4> TrueDestSucc, FalseDestSucc;<br>
+    TrueDestSucc.insert(succ_begin(TrueDest), succ_end(TrueDest));<br>
+    FalseDestSucc.insert(succ_begin(FalseDest), succ_end(FalseDest));<br>
+    BasicBlock *CommonSucc = nullptr;<br>
+    if (TrueDestSucc.count(FalseDest)) {<br>
+      CommonSucc = FalseDest;<br>
+    } else if (FalseDestSucc.count(TrueDest)) {<br>
+      CommonSucc = TrueDest;<br>
+    } else {<br>
+      set_intersect(TrueDestSucc, FalseDestSucc);<br>
+      // If there's one common successor use that.<br>
+      if (TrueDestSucc.size() == 1)<br>
+        CommonSucc = *TrueDestSucc.begin();<br>
+      // If there's more than one pick whichever appears first in the block list<br>
+      // (we can't use the value returned by TrueDestSucc.begin() as it's<br>
+      // unpredicatable which element gets returned).<br>
+      else if (!TrueDestSucc.empty()) {<br>
+        Function *F = TrueDest->getParent();<br>
+        auto IsSucc = [&](BasicBlock &BB) { return TrueDestSucc.count(&BB); };<br>
+        auto It = std::find_if(F->begin(), F->end(), IsSucc);<br>
+        assert(It != F->end() && "Could not find successor in function");<br>
+        CommonSucc = &*It;<br>
+      }<br>
+    }<br>
+    // The common successor has to be dominated by the branch, as otherwise<br>
+    // there will be some other path to the successor that will not be<br>
+    // controlled by this branch so any phi we hoist would be controlled by the<br>
+    // wrong condition. This also takes care of avoiding hoisting of loop back<br>
+    // edges.<br>
+    // TODO: In some cases this could be relaxed if the successor is dominated<br>
+    // by another block that's been hoisted and we can guarantee that the<br>
+    // control flow has been replicated exactly.<br>
+    if (CommonSucc && DT->dominates(BI, CommonSucc))<br>
+      HoistableBranches[BI] = CommonSucc;<br>
+  }<br>
+<br>
+  bool canHoistPHI(PHINode *PN) {<br>
+    // The phi must have loop invariant operands.<br>
+    if (!CurLoop->hasLoopInvariantOperands(PN))<br>
+      return false;<br>
+    // We can hoist phis if the block they are in is the target of hoistable<br>
+    // branches which cover all of the predecessors of the block.<br>
+    SmallPtrSet<BasicBlock *, 8> PredecessorBlocks;<br>
+    BasicBlock *BB = PN->getParent();<br>
+    for (BasicBlock *PredBB : predecessors(BB))<br>
+      PredecessorBlocks.insert(PredBB);<br>
+    // If we have less predecessor blocks than predecessors then the phi will<br>
+    // have more than one incoming value for the same block which we can't<br>
+    // handle.<br>
+    // TODO: This could be handled be erasing some of the duplicate incoming<br>
+    // values.<br>
+    if (PredecessorBlocks.size() != pred_size(BB))<br>
+      return false;<br>
+    for (auto &Pair : HoistableBranches) {<br>
+      if (Pair.second == BB) {<br>
+        // Which blocks are predecessors via this branch depends on if the<br>
+        // branch is triangle-like or diamond-like.<br>
+        if (Pair.first->getSuccessor(0) == BB) {<br>
+          PredecessorBlocks.erase(Pair.first->getParent());<br>
+          PredecessorBlocks.erase(Pair.first->getSuccessor(1));<br>
+        } else if (Pair.first->getSuccessor(1) == BB) {<br>
+          PredecessorBlocks.erase(Pair.first->getParent());<br>
+          PredecessorBlocks.erase(Pair.first->getSuccessor(0));<br>
+        } else {<br>
+          PredecessorBlocks.erase(Pair.first->getSuccessor(0));<br>
+          PredecessorBlocks.erase(Pair.first->getSuccessor(1));<br>
+        }<br>
+      }<br>
+    }<br>
+    // PredecessorBlocks will now be empty if for every predecessor of BB we<br>
+    // found a hoistable branch source.<br>
+    return PredecessorBlocks.empty();<br>
+  }<br>
+<br>
+  BasicBlock *getOrCreateHoistedBlock(BasicBlock *BB) {<br>
+    // If BB has already been hoisted, return that<br>
+    if (HoistDestinationMap.count(BB))<br>
+      return HoistDestinationMap[BB];<br>
+<br>
+    // Check if this block is conditional based on a pending branch<br>
+    auto HasBBAsSuccessor =<br>
+        [&](DenseMap<BranchInst *, BasicBlock *>::value_type &Pair) {<br>
+          return BB != Pair.second && (Pair.first->getSuccessor(0) == BB ||<br>
+                                       Pair.first->getSuccessor(1) == BB);<br>
+        };<br>
+    auto It = std::find_if(HoistableBranches.begin(), HoistableBranches.end(),<br>
+                           HasBBAsSuccessor);<br>
+<br>
+    // If not involved in a pending branch, hoist to preheader<br>
+    BasicBlock *InitialPreheader = CurLoop->getLoopPreheader();<br>
+    if (It == HoistableBranches.end()) {<br>
+      LLVM_DEBUG(dbgs() << "LICM using " << InitialPreheader->getName()<br>
+                        << " as hoist destination for " << BB->getName()<br>
+                        << "\n");<br>
+      HoistDestinationMap[BB] = InitialPreheader;<br>
+      return InitialPreheader;<br>
+    }<br>
+    BranchInst *BI = It->first;<br>
+    assert(std::find_if(++It, HoistableBranches.end(), HasBBAsSuccessor) ==<br>
+               HoistableBranches.end() &&<br>
+           "BB is expected to be the target of at most one branch");<br>
+<br>
+    LLVMContext &C = BB->getContext();<br>
+    BasicBlock *TrueDest = BI->getSuccessor(0);<br>
+    BasicBlock *FalseDest = BI->getSuccessor(1);<br>
+    BasicBlock *CommonSucc = HoistableBranches[BI];<br>
+    BasicBlock *HoistTarget = getOrCreateHoistedBlock(BI->getParent());<br>
+<br>
+    // Create hoisted versions of blocks that currently don't have them<br>
+    auto CreateHoistedBlock = [&](BasicBlock *Orig) {<br>
+      if (HoistDestinationMap.count(Orig))<br>
+        return HoistDestinationMap[Orig];<br>
+      BasicBlock *New =<br>
+          BasicBlock::Create(C, Orig->getName() + ".licm", Orig->getParent());<br>
+      HoistDestinationMap[Orig] = New;<br>
+      DT->addNewBlock(New, HoistTarget);<br>
+      if (CurLoop->getParentLoop())<br>
+        CurLoop->getParentLoop()->addBasicBlockToLoop(New, *LI);<br>
+      ++NumCreatedBlocks;<br>
+      LLVM_DEBUG(dbgs() << "LICM created " << New->getName()<br>
+                        << " as hoist destination for " << Orig->getName()<br>
+                        << "\n");<br>
+      return New;<br>
+    };<br>
+    BasicBlock *HoistTrueDest = CreateHoistedBlock(TrueDest);<br>
+    BasicBlock *HoistFalseDest = CreateHoistedBlock(FalseDest);<br>
+    BasicBlock *HoistCommonSucc = CreateHoistedBlock(CommonSucc);<br>
+<br>
+    // Link up these blocks with branches.<br>
+    if (!HoistCommonSucc->getTerminator()) {<br>
+      // The new common successor we've generated will branch to whatever that<br>
+      // hoist target branched to.<br>
+      BasicBlock *TargetSucc = HoistTarget->getSingleSuccessor();<br>
+      assert(TargetSucc && "Expected hoist target to have a single successor");<br>
+      HoistCommonSucc->moveBefore(TargetSucc);<br>
+      BranchInst::Create(TargetSucc, HoistCommonSucc);<br>
+    }<br>
+    if (!HoistTrueDest->getTerminator()) {<br>
+      HoistTrueDest->moveBefore(HoistCommonSucc);<br>
+      BranchInst::Create(HoistCommonSucc, HoistTrueDest);<br>
+    }<br>
+    if (!HoistFalseDest->getTerminator()) {<br>
+      HoistFalseDest->moveBefore(HoistCommonSucc);<br>
+      BranchInst::Create(HoistCommonSucc, HoistFalseDest);<br>
+    }<br>
+<br>
+    // If BI is being cloned to what was originally the preheader then<br>
+    // HoistCommonSucc will now be the new preheader.<br>
+    if (HoistTarget == InitialPreheader) {<br>
+      // Phis in the loop header now need to use the new preheader.<br>
+      InitialPreheader->replaceSuccessorsPhiUsesWith(HoistCommonSucc);<br>
+      // The new preheader dominates the loop header.<br>
+      DomTreeNode *PreheaderNode = DT->getNode(HoistCommonSucc);<br>
+      DomTreeNode *HeaderNode = DT->getNode(CurLoop->getHeader());<br>
+      DT->changeImmediateDominator(HeaderNode, PreheaderNode);<br>
+      // The preheader hoist destination is now the new preheader, with the<br>
+      // exception of the hoist destination of this branch.<br>
+      for (auto &Pair : HoistDestinationMap)<br>
+        if (Pair.second == InitialPreheader && Pair.first != BI->getParent())<br>
+          Pair.second = HoistCommonSucc;<br>
+    }<br>
+<br>
+    // Now finally clone BI.<br>
+    ReplaceInstWithInst(<br>
+        HoistTarget->getTerminator(),<br>
+        BranchInst::Create(HoistTrueDest, HoistFalseDest, BI->getCondition()));<br>
+    ++NumClonedBranches;<br>
+<br>
+    assert(CurLoop->getLoopPreheader() &&<br>
+           "Hoisting blocks should not have destroyed preheader");<br>
+    return HoistDestinationMap[BB];<br>
+  }<br>
+};<br>
+<br>
 /// Walk the specified region of the CFG (defined by all blocks dominated by<br>
 /// the specified block, and that are in the current loop) in depth first<br>
 /// order w.r.t the DominatorTree.  This allows us to visit definitions before<br>
@@ -451,13 +674,23 @@ bool llvm::hoistRegion(DomTreeNode *N, A<br>
          CurLoop != nullptr && CurAST != nullptr && SafetyInfo != nullptr &&<br>
          "Unexpected input to hoistRegion");<br>
<br>
-  // We want to visit parents before children. We will enque all the parents<br>
-  // before their children in the worklist and process the worklist in order.<br>
-  SmallVector<DomTreeNode *, 16> Worklist = collectChildrenInLoop(N, CurLoop);<br>
+  ControlFlowHoister CFH(LI, DT, CurLoop);<br>
<br>
+  // Keep track of instructions that have been hoisted, as they may need to be<br>
+  // re-hoisted if they end up not dominating all of their uses.<br>
+  SmallVector<Instruction *, 16> HoistedInstructions;<br>
+<br>
+  // Record what the original preheader is, as we'll need it later if we need to<br>
+  // re-hoist instructions.<br>
+  BasicBlock *OriginalPreheader = CurLoop->getLoopPreheader();<br>
+<br>
+  // For PHI hoisting to work we need to hoist blocks before their successors.<br>
+  // We can do this by iterating through the blocks in the loop in reverse<br>
+  // post-order.<br>
+  LoopBlocksRPO Worklist(CurLoop);<br>
+  Worklist.perform(LI);<br>
   bool Changed = false;<br>
-  for (DomTreeNode *DTN : Worklist) {<br>
-    BasicBlock *BB = DTN->getBlock();<br>
+  for (BasicBlock *BB : Worklist) {<br>
     // Only need to process the contents of this block if it is not part of a<br>
     // subloop (which would already have been processed).<br>
     if (inSubLoop(BB, CurLoop, LI))<br>
@@ -483,13 +716,16 @@ bool llvm::hoistRegion(DomTreeNode *N, A<br>
       // Try hoisting the instruction out to the preheader.  We can only do<br>
       // this if all of the operands of the instruction are loop invariant and<br>
       // if it is safe to hoist the instruction.<br>
-      //<br>
+      // TODO: It may be safe to hoist if we are hoisting to a conditional block<br>
+      // and we have accurately duplicated the control flow from the loop header<br>
+      // to that block.<br>
       if (CurLoop->hasLoopInvariantOperands(&I) &&<br>
           canSinkOrHoistInst(I, AA, DT, CurLoop, CurAST, true, ORE) &&<br>
           isSafeToExecuteUnconditionally(<br>
               I, DT, CurLoop, SafetyInfo, ORE,<br>
               CurLoop->getLoopPreheader()->getTerminator())) {<br>
-        hoist(I, DT, CurLoop, SafetyInfo, ORE);<br>
+        hoist(I, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo, ORE);<br>
+        HoistedInstructions.push_back(&I);<br>
         Changed = true;<br>
         continue;<br>
       }<br>
@@ -514,7 +750,9 @@ bool llvm::hoistRegion(DomTreeNode *N, A<br>
         I.replaceAllUsesWith(Product);<br>
         eraseInstruction(I, *SafetyInfo, CurAST);<br>
<br>
-        hoist(*ReciprocalDivisor, DT, CurLoop, SafetyInfo, ORE);<br>
+        hoist(*ReciprocalDivisor, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB),<br>
+              SafetyInfo, ORE);<br>
+        HoistedInstructions.push_back(ReciprocalDivisor);<br>
         Changed = true;<br>
         continue;<br>
       }<br>
@@ -526,13 +764,58 @@ bool llvm::hoistRegion(DomTreeNode *N, A<br>
           CurLoop->hasLoopInvariantOperands(&I) &&<br>
           SafetyInfo->isGuaranteedToExecute(I, DT, CurLoop) &&<br>
           SafetyInfo->doesNotWriteMemoryBefore(I, CurLoop)) {<br>
-        hoist(I, DT, CurLoop, SafetyInfo, ORE);<br>
+        hoist(I, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo, ORE);<br>
+        HoistedInstructions.push_back(&I);<br>
         Changed = true;<br>
         continue;<br>
       }<br>
+<br>
+      if (PHINode *PN = dyn_cast<PHINode>(&I)) {<br>
+        if (CFH.canHoistPHI(PN)) {<br>
+          // Redirect incoming blocks first to ensure that we create hoisted<br>
+          // versions of those blocks before we hoist the phi.<br>
+          for (unsigned int i = 0; i < PN->getNumIncomingValues(); ++i)<br>
+            PN->setIncomingBlock(<br>
+                i, CFH.getOrCreateHoistedBlock(PN->getIncomingBlock(i)));<br>
+          hoist(*PN, DT, CurLoop, CFH.getOrCreateHoistedBlock(BB), SafetyInfo,<br>
+                ORE);<br>
+          assert(DT->dominates(PN, BB) && "Conditional PHIs not expected");<br>
+          Changed = true;<br>
+          continue;<br>
+        }<br>
+      }<br>
+<br>
+      // Remember possibly hoistable branches so we can actually hoist them<br>
+      // later if needed.<br>
+      if (BranchInst *BI = dyn_cast<BranchInst>(&I))<br>
+        CFH.registerPossiblyHoistableBranch(BI);<br>
+    }<br>
+  }<br>
+<br>
+  // If we hoisted instructions to a conditional block they may not dominate<br>
+  // their uses that weren't hoisted (such as phis where some operands are not<br>
+  // loop invariant). If so make them unconditional by moving them to the end of<br>
+  // the original preheader, which is guaranteed to dominate everything in the<br>
+  // loop. We iterate through the instructions in reverse order which ensures<br>
+  // that when we rehoist an instruction we rehoist its operands.<br>
+  Instruction *HoistPoint = OriginalPreheader->getTerminator();<br>
+  for (Instruction *I : reverse(HoistedInstructions)) {<br>
+    if (!llvm::all_of(I->uses(), [&](Use &U) { return DT->dominates(I, U); })) {<br>
+      LLVM_DEBUG(dbgs() << "LICM rehoisting to " << OriginalPreheader->getName()<br>
+                        << ": " << *I << "\n");<br>
+      moveInstructionBefore(*I, *HoistPoint, *SafetyInfo);<br>
+      HoistPoint = I;<br>
+      Changed = true;<br>
     }<br>
   }<br>
<br>
+  // Now that we've finished hoisting make sure that LI and DT are still valid.<br>
+#ifndef NDEBUG<br>
+  assert(DT->verify(DominatorTree::VerificationLevel::Fast) &&<br>
+         "Dominator tree verification failed");<br>
+  LI->verify(*DT);<br>
+#endif<br>
+<br>
   return Changed;<br>
 }<br>
<br>
@@ -1100,9 +1383,9 @@ static bool sink(Instruction &I, LoopInf<br>
 /// is safe to hoist, this instruction is called to do the dirty work.<br>
 ///<br>
 static void hoist(Instruction &I, const DominatorTree *DT, const Loop *CurLoop,<br>
-                  ICFLoopSafetyInfo *SafetyInfo, OptimizationRemarkEmitter *ORE) {<br>
-  auto *Preheader = CurLoop->getLoopPreheader();<br>
-  LLVM_DEBUG(dbgs() << "LICM hoisting to " << Preheader->getName() << ": " << I<br>
+                  BasicBlock *Dest, ICFLoopSafetyInfo *SafetyInfo,<br>
+                  OptimizationRemarkEmitter *ORE) {<br>
+  LLVM_DEBUG(dbgs() << "LICM hoisting to " << Dest->getName() << ": " << I<br>
                     << "\n");<br>
   ORE->emit([&]() {<br>
     return OptimizationRemark(DEBUG_TYPE, "Hoisted", &I) << "hoisting "<br>
@@ -1120,8 +1403,12 @@ static void hoist(Instruction &I, const<br>
       !SafetyInfo->isGuaranteedToExecute(I, DT, CurLoop))<br>
     I.dropUnknownNonDebugMetadata();<br>
<br>
-  // Move the new node to the Preheader, before its terminator.<br>
-  moveInstructionBefore(I, *Preheader->getTerminator(), *SafetyInfo);<br>
+  if (isa<PHINode>(I))<br>
+    // Move the new node to the end of the phi list in the destination block.<br>
+    moveInstructionBefore(I, *Dest->getFirstNonPHI(), *SafetyInfo);<br>
+  else<br>
+    // Move the new node to the destination block, before its terminator.<br>
+    moveInstructionBefore(I, *Dest->getTerminator(), *SafetyInfo);<br>
<br>
   // Do not retain debug locations when we are moving instructions to different<br>
   // basic blocks, because we want to avoid jumpy line tables. Calls, however,<br>
<br>
Added: llvm/trunk/test/Transforms/LICM/hoist-phi.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/hoist-phi.ll?rev=347190&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/hoist-phi.ll?rev=347190&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/LICM/hoist-phi.ll (added)<br>
+++ llvm/trunk/test/Transforms/LICM/hoist-phi.ll Mon Nov 19 03:31:24 2018<br>
@@ -0,0 +1,1164 @@<br>
+; RUN: opt -S -licm < %s | FileCheck %s<br>
+; RUN: opt -passes='require<opt-remark-emit>,loop(licm)' -S < %s | FileCheck %s<br>
+<br>
+; CHECK-LABEL: @triangle_phi<br>
+define void @triangle_phi(i32 %x, i32* %p) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK: %cmp1 = icmp sgt i32 %x, 0<br>
+; CHECK: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: %add = add i32 %x, 1<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: phi i32 [ %add, %[[IF_LICM]] ], [ %x, %entry ]<br>
+; CHECK: store i32 %phi, i32* %p<br>
+; CHECK: %cmp2 = icmp ne i32 %phi, 0<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  %cmp1 = icmp sgt i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %then<br>
+<br>
+if:<br>
+  %add = add i32 %x, 1<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i32 [ %add, %if ], [ %x, %loop ]<br>
+  store i32 %phi, i32* %p<br>
+  %cmp2 = icmp ne i32 %phi, 0<br>
+  br i1 %cmp2, label %loop, label %end<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK-LABEL: @diamond_phi<br>
+define void @diamond_phi(i32 %x, i32* %p) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK: %cmp1 = icmp sgt i32 %x, 0<br>
+; CHECK: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: %add = add i32 %x, 1<br>
+; CHECK: br label %[[THEN_LICM:.*]]<br>
+<br>
+; CHECK: [[ELSE_LICM]]:<br>
+; CHECK: %sub = sub i32 %x, 1<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]<br>
+; CHECK: %phi = phi i32 [ %add, %[[IF_LICM]] ], [ %sub, %[[ELSE_LICM]] ]<br>
+; CHECK: store i32 %phi, i32* %p<br>
+; CHECK: %cmp2 = icmp ne i32 %phi, 0<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  %cmp1 = icmp sgt i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %else<br>
+<br>
+if:<br>
+  %add = add i32 %x, 1<br>
+  br label %then<br>
+<br>
+else:<br>
+  %sub = sub i32 %x, 1<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i32 [ %add, %if ], [ %sub, %else ]<br>
+  store i32 %phi, i32* %p<br>
+  %cmp2 = icmp ne i32 %phi, 0<br>
+  br i1 %cmp2, label %loop, label %end<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
+<br>
+; TODO: This is currently too complicated for us to be able to hoist the phi.<br>
+; CHECK-LABEL: @three_way_phi<br>
+define void @three_way_phi(i32 %x, i32* %p) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0<br>
+; CHECK-DAG: %add = add i32 %x, 1<br>
+; CHECK-DAG: %cmp2 = icmp sgt i32 %add, 0<br>
+; CHECK: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM:.*]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: %sub = sub i32 %x, 1<br>
+; CHECK: br label %loop<br>
+<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  %cmp1 = icmp sgt i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %then<br>
+<br>
+if:<br>
+  %add = add i32 %x, 1<br>
+  %cmp2 = icmp sgt i32 %add, 0<br>
+  br i1 %cmp2, label %if.if, label %then<br>
+<br>
+if.if:<br>
+  %sub = sub i32 %x, 1<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i32 [ 0, %loop ], [ %add, %if ], [ %sub, %if.if ]<br>
+  store i32 %phi, i32* %p<br>
+  %cmp3 = icmp ne i32 %phi, 0<br>
+  br i1 %cmp3, label %loop, label %end<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
+<br>
+; TODO: This is currently too complicated for us to be able to hoist the phi.<br>
+; CHECK-LABEL: @tree_phi<br>
+define void @tree_phi(i32 %x, i32* %p) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0<br>
+; CHECK-DAG: %add = add i32 %x, 1<br>
+; CHECK-DAG: %cmp2 = icmp sgt i32 %add, 0<br>
+; CHECK-DAG: %sub = sub i32 %x, 1<br>
+; CHECK: br label %loop<br>
+<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  %cmp1 = icmp sgt i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %else<br>
+<br>
+if:<br>
+  %add = add i32 %x, 1<br>
+  %cmp2 = icmp sgt i32 %add, 0<br>
+  br i1 %cmp2, label %if.if, label %if.else<br>
+<br>
+if.if:<br>
+  br label %then<br>
+<br>
+if.else:<br>
+  br label %then<br>
+<br>
+else:<br>
+  %sub = sub i32 %x, 1<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i32 [ %add, %if.if ], [ 0, %if.else ], [ %sub, %else ]<br>
+  store i32 %phi, i32* %p<br>
+  %cmp3 = icmp ne i32 %phi, 0<br>
+  br i1 %cmp3, label %loop, label %end<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
+<br>
+; TODO: We can hoist the first phi, but not the second.<br>
+; CHECK-LABEL: @phi_phi<br>
+define void @phi_phi(i32 %x, i32* %p) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0<br>
+; CHECK-DAG: %add = add i32 %x, 1<br>
+; CHECK-DAG: %cmp2 = icmp sgt i32 %add, 0<br>
+; CHECK-DAG: %sub = sub i32 %x, 1<br>
+; CHECK: br i1 %cmp2, label %[[IF_IF_LICM:.*]], label %[[IF_ELSE_LICM:.*]]<br>
+<br>
+; CHECK: [[IF_IF_LICM]]:<br>
+; CHECK: br label %[[IF_THEN_LICM:.*]]<br>
+<br>
+; CHECK: [[IF_ELSE_LICM]]:<br>
+; CHECK: br label %[[IF_THEN_LICM]]<br>
+<br>
+; CHECK: [[IF_THEN_LICM]]:<br>
+; CHECK: %phi1 = phi i32 [ %add, %[[IF_IF_LICM]] ], [ 0, %[[IF_ELSE_LICM]] ]<br>
+; CHECK: br label %loop<br>
+<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  %cmp1 = icmp sgt i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %else<br>
+<br>
+if:<br>
+  %add = add i32 %x, 1<br>
+  %cmp2 = icmp sgt i32 %add, 0<br>
+  br i1 %cmp2, label %if.if, label %if.else<br>
+<br>
+if.if:<br>
+  br label %if.then<br>
+<br>
+if.else:<br>
+  br label %if.then<br>
+<br>
+if.then:<br>
+  %phi1 = phi i32 [ %add, %if.if ], [ 0, %if.else ]<br>
+  br label %then<br>
+<br>
+else:<br>
+  %sub = sub i32 %x, 1<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi2 = phi i32 [ %phi1, %if.then ], [ %sub, %else ]<br>
+  store i32 %phi2, i32* %p<br>
+  %cmp3 = icmp ne i32 %phi2, 0<br>
+  br i1 %cmp3, label %loop, label %end<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
+<br>
+; Check that we correctly duplicate empty control flow.<br>
+; CHECK-LABEL: @empty_triangle_phi<br>
+define i8 @empty_triangle_phi(i32 %x, i32 %y) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK: %cmp1 = icmp eq i32 %x, 0<br>
+; CHECK: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %entry ]<br>
+; CHECK: %cmp2 = icmp eq i32 %y, 0<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  %cmp1 = icmp eq i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %then<br>
+<br>
+if:<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i8 [ 0, %if ], [ 1, %loop ]<br>
+  %cmp2 = icmp eq i32 %y, 0<br>
+  br i1 %cmp2, label %end, label %loop<br>
+<br>
+end:<br>
+  ret i8 %phi<br>
+}<br>
+<br>
+; CHECK-LABEL: @empty_diamond_phi<br>
+define i8 @empty_diamond_phi(i32 %x, i32 %y) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK: %cmp1 = icmp eq i32 %x, 0<br>
+; CHECK: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM:.*]]<br>
+<br>
+; CHECK: [[ELSE_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %[[ELSE_LICM]] ]<br>
+; CHECK: %cmp2 = icmp eq i32 %y, 0<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  %cmp1 = icmp eq i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %else<br>
+<br>
+if:<br>
+  br label %then<br>
+<br>
+else:<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i8 [ 0, %if ], [ 1, %else ]<br>
+  %cmp2 = icmp eq i32 %y, 0<br>
+  br i1 %cmp2, label %end, label %loop<br>
+<br>
+end:<br>
+  ret i8 %phi<br>
+}<br>
+<br>
+; Check that we correctly handle the case that the first thing we try to hoist is a phi.<br>
+; CHECK-LABEL: @empty_triangle_phi_first<br>
+define i8 @empty_triangle_phi_first(i32 %x, i1 %cond) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK: br i1 %cond, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %entry ]<br>
+; CHECK: %cmp = icmp eq i32 %x, 0<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  br i1 %cond, label %if, label %then<br>
+<br>
+if:<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i8 [ 0, %if ], [ 1, %loop ]<br>
+  %cmp = icmp eq i32 %x, 0<br>
+  br i1 %cmp, label %end, label %loop<br>
+<br>
+end:<br>
+  ret i8 %phi<br>
+}<br>
+<br>
+; CHECK-LABEL: @empty_diamond_phi<br>
+define i8 @empty_diamond_phi_first(i32 %x, i1 %cond) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK: br i1 %cond, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM:.*]]<br>
+<br>
+; CHECK: [[ELSE_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %[[ELSE_LICM]] ]<br>
+; CHECK: %cmp = icmp eq i32 %x, 0<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  br i1 %cond, label %if, label %else<br>
+<br>
+if:<br>
+  br label %then<br>
+<br>
+else:<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i8 [ 0, %if ], [ 1, %else ]<br>
+  %cmp = icmp eq i32 %x, 0<br>
+  br i1 %cmp, label %end, label %loop<br>
+<br>
+end:<br>
+  ret i8 %phi<br>
+}<br>
+<br>
+; CHECK-LABEL: @empty_triangle_phi_first<br>
+define i8 @empty_triangle_phi_first_empty_loop_head(i32 %x, i1 %cond) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK: br i1 %cond, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %entry ]<br>
+; CHECK: %cmp = icmp eq i32 %x, 0<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  br label %test<br>
+<br>
+test:<br>
+  br i1 %cond, label %if, label %then<br>
+<br>
+if:<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i8 [ 0, %if ], [ 1, %test ]<br>
+  %cmp = icmp eq i32 %x, 0<br>
+  br i1 %cmp, label %end, label %loop<br>
+<br>
+end:<br>
+  ret i8 %phi<br>
+}<br>
+<br>
+; CHECK-LABEL: @empty_diamond_phi_first_empty_loop_head<br>
+define i8 @empty_diamond_phi_first_empty_loop_head(i32 %x, i1 %cond) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK: br i1 %cond, label %[[IF_LICM:.*]], label %[[ELSE_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM:.*]]<br>
+<br>
+; CHECK: [[ELSE_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: %phi = phi i8 [ 0, %[[IF_LICM]] ], [ 1, %[[ELSE_LICM]] ]<br>
+; CHECK: %cmp = icmp eq i32 %x, 0<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  br label %test<br>
+<br>
+test:<br>
+  br i1 %cond, label %if, label %else<br>
+<br>
+if:<br>
+  br label %then<br>
+<br>
+else:<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i8 [ 0, %if ], [ 1, %else ]<br>
+  %cmp = icmp eq i32 %x, 0<br>
+  br i1 %cmp, label %end, label %loop<br>
+<br>
+end:<br>
+  ret i8 %phi<br>
+}<br>
+<br>
+; The phi is on one branch of a diamond while simultaneously at the end of a<br>
+; triangle. Check that we duplicate the triangle and not the diamond.<br>
+; CHECK-LABEL: @triangle_diamond<br>
+define void @triangle_diamond(i32* %ptr, i32 %x, i32 %y) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %cmp1 = icmp ne i32 %x, 0<br>
+; CHECK-DAG: %cmp2 = icmp ne i32 %y, 0<br>
+; CHECK: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: %phi = phi i32 [ 0, %[[IF_LICM]] ], [ 127, %entry ]<br>
+<br>
+loop:<br>
+  %cmp1 = icmp ne i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %then<br>
+<br>
+if:<br>
+  %cmp2 = icmp ne i32 %y, 0<br>
+  br i1 %cmp2, label %if.then, label %then<br>
+<br>
+then:<br>
+  %phi = phi i32 [ 0, %if ], [ 127, %loop ]<br>
+  store i32 %phi, i32* %ptr<br>
+  br label %end<br>
+<br>
+if.then:<br>
+  br label %end<br>
+<br>
+end:<br>
+  br label %loop<br>
+}<br>
+<br>
+; As the previous, but the end of the diamond is the head of the loop.<br>
+; CHECK-LABEL: @triangle_diamond_backedge<br>
+define void @triangle_diamond_backedge(i32* %ptr, i32 %x, i32 %y) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %cmp1 = icmp ne i32 %x, 0<br>
+; CHECK-DAG: %cmp2 = icmp ne i32 %y, 0<br>
+; CHECK: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: %phi = phi i32 [ 0, %[[IF_LICM]] ], [ 127, %entry ]<br>
+<br>
+loop:<br>
+  %cmp1 = icmp ne i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %then<br>
+<br>
+if:<br>
+  %cmp2 = icmp ne i32 %y, 0<br>
+  br i1 %cmp2, label %backedge, label %then<br>
+<br>
+then:<br>
+  %phi = phi i32 [ 0, %if ], [ 127, %loop ]<br>
+  store i32 %phi, i32* %ptr<br>
+  br label %loop<br>
+<br>
+backedge:<br>
+  br label %loop<br>
+}<br>
+<br>
+; TODO: The inner diamonds can be hoisted, but not currently the outer diamond<br>
+; CHECK-LABEL: @diamonds_inside_diamond<br>
+define void @diamonds_inside_diamond(i32 %x, i32* %p) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0<br>
+; CHECK-DAG: %cmp3 = icmp slt i32 %x, -10<br>
+; CHECK: br i1 %cmp3, label %[[ELSE_IF_LICM:.*]], label %[[ELSE_ELSE_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[ELSE_IF_LICM]]:<br>
+; CHECK: br label %[[ELSE_THEN_LICM:.*]]<br>
+<br>
+; CHECK: [[ELSE_ELSE_LICM]]:<br>
+; CHECK: br label %[[ELSE_THEN_LICM]]<br>
+<br>
+; CHECK: [[ELSE_THEN_LICM]]:<br>
+; CHECK: %phi2 = phi i32 [ 2, %[[ELSE_IF_LICM]] ], [ 3, %[[ELSE_ELSE_LICM]] ]<br>
+; CHECK: %cmp2 = icmp sgt i32 %x, 10<br>
+; CHECK: br i1 %cmp2, label %[[IF_IF_LICM:.*]], label %[[IF_ELSE_LICM:.*]]<br>
+<br>
+; CHECK: [[IF_IF_LICM]]:<br>
+; CHECK: br label %[[IF_THEN_LICM:.*]]<br>
+<br>
+; CHECK: [[IF_ELSE_LICM]]:<br>
+; CHECK: br label %[[IF_THEN_LICM]]<br>
+<br>
+; CHECK: [[IF_THEN_LICM]]:<br>
+; CHECK: %phi1 = phi i32 [ 0, %[[IF_IF_LICM]] ], [ 1, %[[IF_ELSE_LICM]] ]<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  %cmp1 = icmp sgt i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %else<br>
+<br>
+if:<br>
+  %cmp2 = icmp sgt i32 %x, 10<br>
+  br i1 %cmp2, label %if.if, label %if.else<br>
+<br>
+if.if:<br>
+  br label %if.then<br>
+<br>
+if.else:<br>
+  br label %if.then<br>
+<br>
+if.then:<br>
+  %phi1 = phi i32 [ 0, %if.if ], [ 1, %if.else ]<br>
+  br label %then<br>
+<br>
+else:<br>
+  %cmp3 = icmp slt i32 %x, -10<br>
+  br i1 %cmp3, label %else.if, label %else.else<br>
+<br>
+else.if:<br>
+  br label %else.then<br>
+<br>
+else.else:<br>
+  br label %else.then<br>
+<br>
+else.then:<br>
+  %phi2 = phi i32 [ 2, %else.if ], [ 3, %else.else ]<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi3 = phi i32 [ %phi1, %if.then ], [ %phi2, %else.then ]<br>
+  store i32 %phi3, i32* %p<br>
+  %cmp4 = icmp ne i32 %phi3, 0<br>
+  br i1 %cmp4, label %loop, label %end<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
+<br>
+; We can hoist blocks that contain an edge that exits the loop by ignoring that<br>
+; edge in the hoisted block.<br>
+; CHECK-LABEL: @triangle_phi_loopexit<br>
+define void @triangle_phi_loopexit(i32 %x, i32* %p) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %add = add i32 %x, 1<br>
+; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0<br>
+; CHECK-DAG: %cmp2 = icmp sgt i32 10, %add<br>
+; CHECK: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: %phi = phi i32 [ %add, %[[IF_LICM]] ], [ %x, %entry ]<br>
+<br>
+loop:<br>
+  %cmp1 = icmp sgt i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %then<br>
+<br>
+if:<br>
+  %add = add i32 %x, 1<br>
+  %cmp2 = icmp sgt i32 10, %add<br>
+  br i1 %cmp2, label %then, label %end<br>
+<br>
+then:<br>
+  %phi = phi i32 [ %add, %if ], [ %x, %loop ]<br>
+  store i32 %phi, i32* %p<br>
+  %cmp3 = icmp ne i32 %phi, 0<br>
+  br i1 %cmp3, label %loop, label %end<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK-LABEL: @diamond_phi_oneloopexit<br>
+define void @diamond_phi_oneloopexit(i32 %x, i32* %p) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %add = add i32 %x, 1<br>
+; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0<br>
+; CHECK-DAG: %cmp2 = icmp sgt i32 10, %add<br>
+; CHECK: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM:.*]]<br>
+<br>
+; CHECK: [[ELSE_LICM]]:<br>
+; CHECK: %sub = sub i32 %x, 1<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]<br>
+; CHECK: %phi = phi i32 [ %add, %[[IF_LICM]] ], [ %sub, %[[ELSE_LICM]] ]<br>
+; CHECK: %cmp3 = icmp ne i32 %phi, 0<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  %cmp1 = icmp sgt i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %else<br>
+<br>
+if:<br>
+  %add = add i32 %x, 1<br>
+  %cmp2 = icmp sgt i32 10, %add<br>
+  br i1 %cmp2, label %then, label %end<br>
+<br>
+else:<br>
+  %sub = sub i32 %x, 1<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i32 [ %add, %if ], [ %sub, %else ]<br>
+  store i32 %phi, i32* %p<br>
+  %cmp3 = icmp ne i32 %phi, 0<br>
+  br i1 %cmp3, label %loop, label %end<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
+<br>
+; CHECK-LABEL: @diamond_phi_twoloopexit<br>
+define void @diamond_phi_twoloopexit(i32 %x, i32* %p) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %sub = sub i32 %x, 1<br>
+; CHECK-DAG: %add = add i32 %x, 1<br>
+; CHECK-DAG: %cmp1 = icmp sgt i32 %x, 0<br>
+; CHECK-DAG: %cmp2 = icmp sgt i32 10, %add<br>
+; CHECK-DAG: %cmp3 = icmp sgt i32 10, %sub<br>
+; CHECK: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM:.*]]<br>
+<br>
+; CHECK: [[ELSE_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]<br>
+; CHECK: %phi = phi i32 [ %add, %[[IF_LICM]] ], [ %sub, %[[ELSE_LICM]] ]<br>
+; CHECK: %cmp4 = icmp ne i32 %phi, 0<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  %cmp1 = icmp sgt i32 %x, 0<br>
+  br i1 %cmp1, label %if, label %else<br>
+<br>
+if:<br>
+  %add = add i32 %x, 1<br>
+  %cmp2 = icmp sgt i32 10, %add<br>
+  br i1 %cmp2, label %then, label %end<br>
+<br>
+else:<br>
+  %sub = sub i32 %x, 1<br>
+  %cmp3 = icmp sgt i32 10, %sub<br>
+  br i1 %cmp3, label %then, label %end<br>
+<br>
+then:<br>
+  %phi = phi i32 [ %add, %if ], [ %sub, %else ]<br>
+  store i32 %phi, i32* %p<br>
+  %cmp4 = icmp ne i32 %phi, 0<br>
+  br i1 %cmp4, label %loop, label %end<br>
+<br>
+end:<br>
+  ret void<br>
+}<br>
+<br>
+; The store cannot be hoisted, so add and shr cannot be hoisted into a<br>
+; conditional block.<br>
+; CHECK-LABEL: @conditional_use<br>
+define void @conditional_use(i32 %x, i32* %p) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %cond = icmp ugt i32 %x, 0<br>
+; CHECK-DAG: %add = add i32 %x, 5<br>
+; CHECK-DAG: %shr = ashr i32 %add, 1<br>
+; CHECK: br label %loop<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  %cond = icmp ugt i32 %x, 0<br>
+  br i1 %cond, label %if, label %else<br>
+<br>
+; CHECK-LABEL: if:<br>
+; CHECK: store i32 %shr, i32* %p, align 4<br>
+if:<br>
+  %add = add i32 %x, 5<br>
+  %shr = ashr i32 %add, 1<br>
+  store i32 %shr, i32* %p, align 4<br>
+  br label %then<br>
+<br>
+else:<br>
+  br label %then<br>
+<br>
+then:<br>
+  br label %loop<br>
+}<br>
+<br>
+; A diamond with two triangles on the left and one on the right. This test is<br>
+; to check that we have a unique loop preheader when we hoist the store (and so<br>
+; don't fail an assertion).<br>
+; CHECK-LABEL: @triangles_in_diamond<br>
+define void @triangles_in_diamond(i32* %ptr) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK: store i32 0, i32* %ptr, align 4<br>
+; CHECK: br label %loop<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  br i1 undef, label %left_triangle_1, label %right_triangle<br>
+<br>
+left_triangle_1:<br>
+  br i1 undef, label %left_triangle_1_if, label %left_triangle_2<br>
+<br>
+left_triangle_1_if:<br>
+  br label %left_triangle_2<br>
+<br>
+left_triangle_2:<br>
+  br i1 undef, label %left_triangle_2_if, label %left_triangle_2_then<br>
+<br>
+left_triangle_2_if:<br>
+  br label %left_triangle_2_then<br>
+<br>
+left_triangle_2_then:<br>
+  br label %loop.end<br>
+<br>
+right_triangle:<br>
+  br i1 undef, label %right_triangle.if, label %right_triangle.then<br>
+<br>
+right_triangle.if:<br>
+  br label %right_triangle.then<br>
+<br>
+right_triangle.then:<br>
+  br label %loop.end<br>
+<br>
+loop.end:<br>
+  store i32 0, i32* %ptr, align 4<br>
+  br label %loop<br>
+}<br>
+<br>
+; %cmp dominates its used after being hoisted, but not after %brmerge is rehoisted<br>
+; CHECK-LABEL: @rehoist<br>
+define void @rehoist(i8* %this, i32 %x) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %sub = add nsw i32 %x, -1<br>
+; CHECK-DAG: %fptr = bitcast i8* %this to void (i8*)*<br>
+; CHECK-DAG: %cmp = icmp eq i32 0, %sub<br>
+; CHECK-DAG: %brmerge = or i1 %cmp, true<br>
+entry:<br>
+  %sub = add nsw i32 %x, -1<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  br i1 undef, label %if1, label %else1<br>
+<br>
+if1:<br>
+  %fptr = bitcast i8* %this to void (i8*)*<br>
+  call void %fptr(i8* %this)<br>
+  br label %then1<br>
+<br>
+else1:<br>
+  br label %then1<br>
+<br>
+then1:<br>
+  %cmp = icmp eq i32 0, %sub<br>
+  br i1 %cmp, label %end, label %else2<br>
+<br>
+else2:<br>
+  %brmerge = or i1 %cmp, true<br>
+  br i1 %brmerge, label %if3, label %end<br>
+<br>
+if3:<br>
+  br label %end<br>
+<br>
+end:<br>
+  br label %loop<br>
+}<br>
+<br>
+; A test case that uses empty blocks in a way that can cause control flow<br>
+; hoisting to get confused.<br>
+; CHECK-LABEL: @empty_blocks_multiple_conditional_branches<br>
+define void @empty_blocks_multiple_conditional_branches(float %arg, float* %ptr) {<br>
+; CHECK-LABEL: entry<br>
+; CHECK-DAG: %div1 = fmul float %arg, 4.000000e+00<br>
+; CHECK-DAG: %div2 = fmul float %arg, 2.000000e+00<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; The exact path to the phi isn't checked here, because it depends on whether<br>
+; cond2 or cond3 is hoisted first<br>
+; CHECK: %phi = phi float [ 0.000000e+00, %{{.*}} ], [ %div1, %{{.*}} ]<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  br i1 undef, label %backedge2, label %cond1<br>
+<br>
+cond1:<br>
+  br i1 undef, label %cond1.if, label %cond1.else<br>
+<br>
+cond1.else:<br>
+  br label %cond3<br>
+<br>
+cond1.if:<br>
+  br label %cond1.if.next<br>
+<br>
+cond1.if.next:<br>
+  br label %cond2<br>
+<br>
+cond2:<br>
+  %div1 = fmul float %arg, 4.000000e+00<br>
+  br i1 undef, label %cond2.if, label %cond2.then<br>
+<br>
+cond2.if:<br>
+  br label %cond2.then<br>
+<br>
+cond2.then:<br>
+  %phi = phi float [ 0.000000e+00, %cond2 ], [ %div1, %cond2.if ]<br>
+  store float %phi, float* %ptr<br>
+  br label %backedge2<br>
+<br>
+cond3:<br>
+  br i1 undef, label %cond3.then, label %cond3.if<br>
+<br>
+cond3.if:<br>
+  %div2 = fmul float %arg, 2.000000e+00<br>
+  store float %div2, float* %ptr<br>
+  br label %cond3.then<br>
+<br>
+cond3.then:<br>
+  br label %loop<br>
+<br>
+backedge2:<br>
+  br label %loop<br>
+}<br>
+<br>
+; We can't do much here, so mainly just check that we don't crash.<br>
+; CHECK-LABEL: @many_path_phi<br>
+define void @many_path_phi(i32* %ptr1, i32* %ptr2) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %gep3 = getelementptr inbounds i32, i32* %ptr2, i32 2<br>
+; CHECK-DAG: %gep2 = getelementptr inbounds i32, i32* %ptr2, i32 2<br>
+; CHECK: br label %loop<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  %phi1 = phi i32 [ 0, %entry ], [ %phi2, %end ]<br>
+  %cmp1 = icmp ugt i32 %phi1, 3<br>
+  br i1 %cmp1, label %cond2, label %cond1<br>
+<br>
+cond1:<br>
+  br i1 undef, label %end, label %cond1.else<br>
+<br>
+cond1.else:<br>
+  %gep2 = getelementptr inbounds i32, i32* %ptr2, i32 2<br>
+  %val2 = load i32, i32* %gep2, align 4<br>
+  %cmp2 = icmp eq i32 %val2, 13<br>
+  br i1 %cmp2, label %cond1.end, label %end<br>
+<br>
+cond1.end:<br>
+  br label %end<br>
+<br>
+cond2:<br>
+  br i1 undef, label %end, label %cond2.else<br>
+<br>
+cond2.else:<br>
+  %gep3 = getelementptr inbounds i32, i32* %ptr2, i32 2<br>
+  %val3 = load i32, i32* %gep3, align 4<br>
+  %cmp3 = icmp eq i32 %val3, 13<br>
+  br i1 %cmp3, label %cond2.end, label %end<br>
+<br>
+cond2.end:<br>
+  br label %end<br>
+<br>
+end:<br>
+  %phi2 = phi i32 [ 1, %cond1 ], [ 2, %cond1.else ], [ 3, %cond1.end ], [ 4, %cond2 ], [ 5, %cond2.else ], [ 6, %cond2.end ]<br>
+  br label %loop<br>
+}<br>
+<br>
+; Check that we correctly handle the hoisting of %gep when theres a critical<br>
+; edge that branches to the preheader.<br>
+; CHECK-LABEL: @crit_edge<br>
+define void @crit_edge(i32* %ptr, i32 %idx, i1 %cond1, i1 %cond2) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK: %gep = getelementptr inbounds i32, i32* %ptr, i32 %idx<br>
+; CHECK: br label %preheader<br>
+entry:<br>
+  br label %preheader<br>
+<br>
+preheader:<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  br i1 %cond1, label %then, label %if<br>
+<br>
+if:<br>
+  %gep = getelementptr inbounds i32, i32* %ptr, i32 %idx<br>
+  %val = load i32, i32* %gep<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi = phi i32 [ %val, %if ], [ 0, %loop ]<br>
+  store i32 %phi, i32* %ptr<br>
+  br i1 %cond2, label %loop, label %crit_edge<br>
+<br>
+crit_edge:<br>
+  br label %preheader<br>
+}<br>
+<br>
+; Check that the conditional sub is correctly hoisted from the inner loop to the<br>
+; preheader of the outer loop.<br>
+; CHECK-LABEL: @hoist_from_innermost_loop<br>
+define void @hoist_from_innermost_loop(i32 %nx, i32* %ptr) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %sub = sub nsw i32 0, %nx<br>
+; CHECK: br label %outer_loop<br>
+entry:<br>
+  br label %outer_loop<br>
+<br>
+outer_loop:<br>
+  br label %middle_loop<br>
+<br>
+middle_loop:<br>
+  br label %inner_loop<br>
+<br>
+inner_loop:<br>
+  br i1 undef, label %inner_loop_end, label %if<br>
+<br>
+if:<br>
+  %sub = sub nsw i32 0, %nx<br>
+  store i32 %sub, i32* %ptr, align 4<br>
+  br label %inner_loop_end<br>
+<br>
+inner_loop_end:<br>
+  br i1 undef, label %inner_loop, label %middle_loop_end<br>
+<br>
+middle_loop_end:<br>
+  br i1 undef, label %middle_loop, label %outer_loop_end<br>
+<br>
+outer_loop_end:<br>
+  br label %outer_loop<br>
+}<br>
+<br>
+; We have a diamond starting from %if, but %if.if is also reachable from %loop,<br>
+; so %gep should not be conditionally hoisted.<br>
+; CHECK-LABEL: @diamond_with_extra_in_edge<br>
+define void @diamond_with_extra_in_edge(i32* %ptr1, i32* %ptr2, i32 %arg) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %cmp2 = icmp ne i32 0, %arg<br>
+; CHECK-DAG: %gep = getelementptr i32, i32* %ptr1, i32 4<br>
+; CHECK: br label %loop<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  %phi1 = phi i32 [ 0, %entry ], [ %phi2, %then ]<br>
+  %cmp1 = icmp ugt i32 16, %phi1<br>
+  br i1 %cmp1, label %if, label %if.if<br>
+<br>
+if:<br>
+  %cmp2 = icmp ne i32 0, %arg<br>
+  br i1 %cmp2, label %if.if, label %if.else<br>
+<br>
+if.if:<br>
+  %gep = getelementptr i32, i32* %ptr1, i32 4<br>
+  %val = load i32, i32* %gep, align 4<br>
+  br label %then<br>
+<br>
+if.else:<br>
+  br label %then<br>
+<br>
+then:<br>
+  %phi2 = phi i32 [ %val, %if.if ], [ %phi1, %if.else ]<br>
+  store i32 %phi2, i32* %ptr2, align 4<br>
+  br label %loop<br>
+}<br>
+<br>
+; %loop/%if/%then form a triangle, but %loop/%if/%then/%end also form a diamond.<br>
+; The triangle should be picked for conditional hoisting.<br>
+; CHECK-LABEL: @both_triangle_and_diamond<br>
+define void @both_triangle_and_diamond(i32* %ptr1, i32* %ptr2, i32 %arg) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %cmp1 = icmp ne i32 0, %arg<br>
+; CHECK-DAG: %gep = getelementptr i32, i32* %ptr1, i32 4<br>
+; CHECK: br i1 %cmp1, label %[[IF_LICM:.*]], label %[[THEN_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[IF_LICM]]:<br>
+; CHECK: br label %[[THEN_LICM]]<br>
+<br>
+; CHECK: [[THEN_LICM]]:<br>
+; CHECK: %phi2 = phi i32 [ 0, %[[IF_LICM]] ], [ 1, %entry ]<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  %phi1 = phi i32 [ 0, %entry ], [ %phi3, %end ]<br>
+  %cmp1 = icmp ne i32 0, %arg<br>
+  br i1 %cmp1, label %if, label %then<br>
+<br>
+if:<br>
+  %gep = getelementptr i32, i32* %ptr1, i32 4<br>
+  %val = load i32, i32* %gep, align 4<br>
+  %cmp2 = icmp ugt i32 16, %phi1<br>
+  br i1 %cmp2, label %end, label %then<br>
+<br>
+then:<br>
+  %phi2 = phi i32 [ 0, %if ], [ 1, %loop ]<br>
+  br label %end<br>
+<br>
+end:<br>
+  %phi3 = phi i32 [ %phi2, %then ], [ %val, %if ]<br>
+  store i32 %phi3, i32* %ptr2, align 4<br>
+  br label %loop<br>
+}<br>
+<br>
+; We shouldn't duplicate the branch at the end of %loop and should instead hoist<br>
+; %val to %entry.<br>
+; CHECK-LABEL: @same_destination_branch<br>
+define i32 @same_destination_branch(i32 %arg1, i32 %arg2) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %cmp1 = icmp ne i32 %arg2, 0<br>
+; CHECK-DAG: %val = add i32 %arg1, 1<br>
+; CHECK: br label %loop<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  %phi = phi i32 [ 0, %entry ], [ %add, %then ]<br>
+  %add = add i32 %phi, 1<br>
+  %cmp1 = icmp ne i32 %arg2, 0<br>
+  br i1 %cmp1, label %if, label %if<br>
+<br>
+if:<br>
+  %val = add i32 %arg1, 1<br>
+  br label %then<br>
+<br>
+then:<br>
+  %cmp2 = icmp ne i32 %val, %phi<br>
+  br i1 %cmp2, label %loop, label %end<br>
+<br>
+end:<br>
+  ret i32 %val<br>
+}<br>
+<br>
+; Diamond-like control flow but the left/right blocks actually have the same<br>
+; destinations.<br>
+; TODO: We could potentially hoist all of phi2-4, but currently only hoist phi2.<br>
+; CHECK-LABEL: @diamond_like_same_destinations<br>
+define i32 @diamond_like_same_destinations(i32 %arg1, i32 %arg2) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK-DAG: %cmp1 = icmp ne i32 %arg1, 0<br>
+; CHECK-DAG: %cmp2 = icmp ugt i32 %arg2, 1<br>
+; CHECK-DAG: %cmp3 = icmp ugt i32 %arg2, 2<br>
+; CHECK: br i1 %cmp1, label %[[LEFT1_LICM:.*]], label %[[RIGHT1_LICM:.*]]<br>
+entry:<br>
+  br label %loop<br>
+<br>
+; CHECK: [[LEFT1_LICM]]:<br>
+; CHECK: br label %[[LEFT2_LICM:.*]]<br>
+<br>
+; CHECK: [[RIGHT1_LICM]]:<br>
+; CHECK: br label %[[LEFT2_LICM]]<br>
+<br>
+; CHECK: [[LEFT2_LICM]]:<br>
+; CHECK: %phi2 = phi i32 [ 0, %[[LEFT1_LICM]] ], [ 1, %[[RIGHT1_LICM]] ]<br>
+; CHECK: br label %loop<br>
+<br>
+loop:<br>
+  %phi1 = phi i32 [ 0, %entry ], [ %add, %loopend ]<br>
+  %add = add i32 %phi1, 1<br>
+  %cmp1 = icmp ne i32 %arg1, 0<br>
+  br i1 %cmp1, label %left1, label %right1<br>
+<br>
+left1:<br>
+  %cmp2 = icmp ugt i32 %arg2, 1<br>
+  br i1 %cmp2, label %left2, label %right2<br>
+<br>
+right1:<br>
+  %cmp3 = icmp ugt i32 %arg2, 2<br>
+  br i1 %cmp3, label %left2, label %right2<br>
+<br>
+left2:<br>
+  %phi2 = phi i32 [ 0, %left1 ], [ 1, %right1 ]<br>
+  br label %loopend<br>
+<br>
+right2:<br>
+  %phi3 = phi i32 [ 2, %left1 ], [ 3, %right1 ]<br>
+  br label %loopend<br>
+<br>
+loopend:<br>
+  %phi4 = phi i32 [ %phi2, %left2 ], [ %phi3, %right2 ]<br>
+  %cmp4 = icmp ne i32 %phi1, 32<br>
+  br i1 %cmp4, label %loop, label %end<br>
+<br>
+end:<br>
+  ret i32 %phi4<br>
+}<br>
+<br>
+; A phi with multiple incoming values for the same block due to a branch with<br>
+; two destinations that are actually the same. We can't hoist this.<br>
+; TODO: This could be hoisted by erasing one of the incoming values.<br>
+; CHECK-LABEL: @phi_multiple_values_same_block<br>
+define i32 @phi_multiple_values_same_block(i32 %arg) {<br>
+; CHECK-LABEL: entry:<br>
+; CHECK: %cmp = icmp sgt i32 %arg, 4<br>
+; CHECK-NOT: phi<br>
+; CHECK: br label %loop<br>
+entry:<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  %cmp = icmp sgt i32 %arg, 4<br>
+  br i1 %cmp, label %if, label %then<br>
+<br>
+if:<br>
+  br i1 undef, label %then, label %then<br>
+<br>
+then:<br>
+  %phi = phi i32 [ %arg, %loop ], [ 1, %if ], [ 1, %if ]<br>
+  br i1 undef, label %exit, label %loop<br>
+<br>
+exit:<br>
+  ret i32 %phi<br>
+}<br>
<br>
Modified: llvm/trunk/test/Transforms/LoopVectorize/invariant-store-vectorization.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopVectorize/invariant-store-vectorization.ll?rev=347190&r1=347189&r2=347190&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopVectorize/invariant-store-vectorization.ll?rev=347190&r1=347189&r2=347190&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/LoopVectorize/invariant-store-vectorization.ll (original)<br>
+++ llvm/trunk/test/Transforms/LoopVectorize/invariant-store-vectorization.ll Mon Nov 19 03:31:24 2018<br>
@@ -266,19 +266,26 @@ for.end:<br>
 ; variant/invariant values being stored to invariant address.<br>
 ; test checks that the last element of the phi is extracted and scalar stored<br>
 ; into the uniform address within the loop.<br>
-; Since the condition and the phi is loop invariant, they are LICM'ed after<br>
+; Since the condition and the phi is loop invariant, they are LICM'ed before<br>
 ; vectorization.<br>
 ; CHECK-LABEL: inv_val_store_to_inv_address_conditional_inv<br>
 ; CHECK-NEXT:  entry:<br>
+; CHECK-NEXT:    [[B1:%.*]] = bitcast i32* [[B:%.*]] to i8*<br>
+; CHECK-NEXT:    [[A4:%.*]] = bitcast i32* [[A:%.*]] to i8*<br>
 ; CHECK-NEXT:    [[NTRUNC:%.*]] = trunc i64 [[N:%.*]] to i32<br>
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[NTRUNC]], [[K:%.*]]<br>
+; CHECK-NEXT:    br i1 [[CMP]], label %[[COND_STORE_LICM:.*]], label %[[COND_STORE_K_LICM:.*]]<br>
+; CHECK:       [[COND_STORE_LICM]]:<br>
+; CHECK-NEXT:    br label %[[LATCH_LICM:.*]]<br>
+; CHECK:       [[COND_STORE_K_LICM]]:<br>
+; CHECK-NEXT:    br label %[[LATCH_LICM]]<br>
+; CHECK:       [[LATCH_LICM]]:<br>
+; CHECK-NEXT:    [[STOREVAL:%.*]] = phi i32 [ [[NTRUNC]], %[[COND_STORE_LICM]] ], [ [[K]], %[[COND_STORE_K_LICM]] ]<br>
 ; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i64 [[N]], 1<br>
 ; CHECK-NEXT:    [[SMAX:%.*]] = select i1 [[TMP0]], i64 [[N]], i64 1<br>
 ; CHECK-NEXT:    [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[SMAX]], 4<br>
 ; CHECK-NEXT:    br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]]<br>
 ; CHECK:       vector.memcheck:<br>
-; CHECK-NEXT:    [[A4:%.*]] = bitcast i32* [[A:%.*]] to i8*<br>
-; CHECK-NEXT:    [[B1:%.*]] = bitcast i32* [[B:%.*]] to i8*<br>
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[N]], 1<br>
 ; CHECK-NEXT:    [[SMAX2:%.*]] = select i1 [[TMP1]], i64 [[N]], i64 1<br>
 ; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i32, i32* [[B]], i64 [[SMAX2]]<br>
@@ -291,17 +298,13 @@ for.end:<br>
 ; CHECK-NEXT:    [[N_VEC:%.*]] = and i64 [[SMAX]], 9223372036854775804<br>
 ; CHECK-NEXT:    [[BROADCAST_SPLATINSERT5:%.*]] = insertelement <4 x i32> undef, i32 [[NTRUNC]], i32 0<br>
 ; CHECK-NEXT:    [[BROADCAST_SPLAT6:%.*]] = shufflevector <4 x i32> [[BROADCAST_SPLATINSERT5]], <4 x i32> undef, <4 x i32> zeroinitializer<br>
-; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <4 x i1> undef, i1 [[CMP]], i32 3<br>
-; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <4 x i32> undef, i32 [[K]], i32 3<br>
-; CHECK-NEXT:    [[PREDPHI:%.*]] = select <4 x i1> [[TMP2]], <4 x i32> [[BROADCAST_SPLAT6]], <4 x i32> [[TMP3]]<br>
-; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <4 x i32> [[PREDPHI]], i32 3<br>
 ; CHECK-NEXT:    br label [[VECTOR_BODY:%.*]]<br>
 ; CHECK:       vector.body:<br>
 ; CHECK-NEXT:    [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ]<br>
 ; CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[B]], i64 [[INDEX]]<br>
 ; CHECK-NEXT:    [[TMP7:%.*]] = bitcast i32* [[TMP6]] to <4 x i32>*<br>
 ; CHECK-NEXT:    store <4 x i32> [[BROADCAST_SPLAT6]], <4 x i32>* [[TMP7]], align 4<br>
-; CHECK-NEXT:    store i32 [[TMP5]], i32* [[A]], align 4<br>
+; CHECK-NEXT:    store i32 [[STOREVAL]], i32* [[A]], align 4<br>
 ; CHECK-NEXT:    [[INDEX_NEXT]] = add i64 [[INDEX]], 4<br>
 ; CHECK-NEXT:    [[TMP8:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]]<br>
 ; CHECK-NEXT:    br i1 [[TMP8]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]]<br>
@@ -321,7 +324,6 @@ for.end:<br>
 ; CHECK:       cond_store_k:<br>
 ; CHECK-NEXT:    br label [[LATCH]]<br>
 ; CHECK:       latch:<br>
-; CHECK-NEXT:    [[STOREVAL:%.*]] = phi i32 [ [[NTRUNC]], [[COND_STORE]] ], [ [[K]], [[COND_STORE_K]] ]<br>
 ; CHECK-NEXT:    store i32 [[STOREVAL]], i32* [[A]], align 4<br>
 ; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i64 [[I]], 1<br>
 ; CHECK-NEXT:    [[COND:%.*]] = icmp slt i64 [[I_NEXT]], [[N]]<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>