[llvm] [LoopRotate] Remove canRotateDeoptimizingLatchExit and multi-rotate (PR #162482)

Marek Sedláček via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 8 06:34:16 PDT 2025


https://github.com/mark-sed created https://github.com/llvm/llvm-project/pull/162482

After further investigation of improvements to runtime unrolling and to it connected loop rotation (with my attempts in https://github.com/llvm/llvm-project/pull/146540 and https://github.com/llvm/llvm-project/pull/148243) I have looked more into loop rotation and the existing profitability checks.

The `canRotateDeoptimizingLatchExit` check does not seem to work as intended. It was introduced in https://gitlab.azulsystems.com/dev/orca/-/commit/2f6987ba61cc31c16c64f511e5cbc76b52dc67b3 for the loop-rotate-multi-flag, where this flag was disabled and there was an intent to enable it by default later (https://reviews.llvm.org/D73058) and this has not happen even 5 years later.

I have done multiple experiments in our downstream with multi-rotate and with this check. We suggest removal of this heuristic and multi-rotate as well.

Note that the diff is big, but it's just removal of while loop and indentation change.

After this patch I would like to continue here and propose adding a computability check for exit count, but that will be in a separate PR.

Requests for review: @annamthomas @fhahn @davemgreen 

>From 777d0609777691ad0fe153e11e9170adbf58949d Mon Sep 17 00:00:00 2001
From: Marek Sedlacek <msedlacek at azul.com>
Date: Wed, 8 Oct 2025 13:01:13 +0000
Subject: [PATCH] This patch removes canRotateDeoptimizingLatchExit check from
 loop roate and connected multi rotation option for loop roate
 (-loop-rotate-multi option).

Multi rotation was never enabled by default and seems like unfinished
attempt at improving loop rotation.
---
 .../Transforms/Utils/LoopRotationUtils.cpp    | 941 ++++++++----------
 .../LoopRotate/multiple-deopt-exits.ll        | 164 ---
 .../Transforms/LoopRotate/multiple-exits.ll   | 236 -----
 3 files changed, 437 insertions(+), 904 deletions(-)
 delete mode 100644 llvm/test/Transforms/LoopRotate/multiple-deopt-exits.ll
 delete mode 100644 llvm/test/Transforms/LoopRotate/multiple-exits.ll

diff --git a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
index 7cc9ff8b11139..f0f7bbb64da32 100644
--- a/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopRotationUtils.cpp
@@ -45,12 +45,6 @@ STATISTIC(NumInstrsHoisted,
           "Number of instructions hoisted into loop preheader");
 STATISTIC(NumInstrsDuplicated,
           "Number of instructions cloned into loop preheader");
-STATISTIC(NumRotated, "Number of loops rotated");
-
-static cl::opt<bool>
-    MultiRotate("loop-rotate-multi", cl::init(false), cl::Hidden,
-                cl::desc("Allow loop rotation multiple times in order to reach "
-                         "a better latch exit"));
 
 // Probability that a rotated loop has zero trip count / is never entered.
 static constexpr uint32_t ZeroTripCountWeights[] = {1, 127};
@@ -206,50 +200,6 @@ static bool profitableToRotateLoopExitingLatch(Loop *L) {
   return false;
 }
 
-// Check that latch exit is deoptimizing (which means - very unlikely to happen)
-// and there is another exit from the loop which is non-deoptimizing.
-// If we rotate latch to that exit our loop has a better chance of being fully
-// canonical.
-//
-// It can give false positives in some rare cases.
-static bool canRotateDeoptimizingLatchExit(Loop *L) {
-  BasicBlock *Latch = L->getLoopLatch();
-  assert(Latch && "need latch");
-  BranchInst *BI = dyn_cast<BranchInst>(Latch->getTerminator());
-  // Need normal exiting latch.
-  if (!BI || !BI->isConditional())
-    return false;
-
-  BasicBlock *Exit = BI->getSuccessor(1);
-  if (L->contains(Exit))
-    Exit = BI->getSuccessor(0);
-
-  // Latch exit is non-deoptimizing, no need to rotate.
-  if (!Exit->getPostdominatingDeoptimizeCall())
-    return false;
-
-  SmallVector<BasicBlock *, 4> Exits;
-  L->getUniqueExitBlocks(Exits);
-  if (!Exits.empty()) {
-    // There is at least one non-deoptimizing exit.
-    //
-    // Note, that BasicBlock::getPostdominatingDeoptimizeCall is not exact,
-    // as it can conservatively return false for deoptimizing exits with
-    // complex enough control flow down to deoptimize call.
-    //
-    // That means here we can report success for a case where
-    // all exits are deoptimizing but one of them has complex enough
-    // control flow (e.g. with loops).
-    //
-    // That should be a very rare case and false positives for this function
-    // have compile-time effect only.
-    return any_of(Exits, [](const BasicBlock *BB) {
-      return !BB->getPostdominatingDeoptimizeCall();
-    });
-  }
-  return false;
-}
-
 static void updateBranchWeights(BranchInst &PreHeaderBI, BranchInst &LoopBI,
                                 bool HasConditionalPreHeader,
                                 bool SuccsSwapped) {
@@ -387,506 +337,489 @@ static void updateBranchWeights(BranchInst &PreHeaderBI, BranchInst &LoopBI,
 /// rotation. LoopRotate should be repeatable and converge to a canonical
 /// form. This property is satisfied because simplifying the loop latch can only
 /// happen once across multiple invocations of the LoopRotate pass.
-///
-/// If -loop-rotate-multi is enabled we can do multiple rotations in one go
-/// so to reach a suitable (non-deoptimizing) exit.
 bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
   // If the loop has only one block then there is not much to rotate.
   if (L->getBlocks().size() == 1)
     return false;
 
   bool Rotated = false;
-  do {
-    BasicBlock *OrigHeader = L->getHeader();
-    BasicBlock *OrigLatch = L->getLoopLatch();
-
-    BranchInst *BI = dyn_cast<BranchInst>(OrigHeader->getTerminator());
-    if (!BI || BI->isUnconditional())
+  BasicBlock *OrigHeader = L->getHeader();
+  BasicBlock *OrigLatch = L->getLoopLatch();
+
+  BranchInst *BI = dyn_cast<BranchInst>(OrigHeader->getTerminator());
+  if (!BI || BI->isUnconditional())
+    return Rotated;
+
+  // If the loop header is not one of the loop exiting blocks then
+  // either this loop is already rotated or it is not
+  // suitable for loop rotation transformations.
+  if (!L->isLoopExiting(OrigHeader))
+    return Rotated;
+
+  // If the loop latch already contains a branch that leaves the loop then the
+  // loop is already rotated.
+  if (!OrigLatch)
+    return Rotated;
+
+  // Rotate if the loop latch was just simplified. Or if it makes the loop exit
+  // count computable. Or if we think it will be profitable.
+  if (L->isLoopExiting(OrigLatch) && !SimplifiedLatch && IsUtilMode == false &&
+      !profitableToRotateLoopExitingLatch(L))
+    return Rotated;
+
+  // Check size of original header and reject loop if it is very big or we can't
+  // duplicate blocks inside it.
+  {
+    SmallPtrSet<const Value *, 32> EphValues;
+    CodeMetrics::collectEphemeralValues(L, AC, EphValues);
+
+    CodeMetrics Metrics;
+    Metrics.analyzeBasicBlock(OrigHeader, *TTI, EphValues, PrepareForLTO);
+    if (Metrics.notDuplicatable) {
+      LLVM_DEBUG(
+                  dbgs() << "LoopRotation: NOT rotating - contains non-duplicatable"
+                  << " instructions: ";
+                  L->dump());
       return Rotated;
-
-    // If the loop header is not one of the loop exiting blocks then
-    // either this loop is already rotated or it is not
-    // suitable for loop rotation transformations.
-    if (!L->isLoopExiting(OrigHeader))
-      return Rotated;
-
-    // If the loop latch already contains a branch that leaves the loop then the
-    // loop is already rotated.
-    if (!OrigLatch)
+    }
+    if (Metrics.Convergence != ConvergenceKind::None) {
+      LLVM_DEBUG(dbgs() << "LoopRotation: NOT rotating - contains convergent "
+                  "instructions: ";
+                  L->dump());
       return Rotated;
-
-    // Rotate if either the loop latch does *not* exit the loop, or if the loop
-    // latch was just simplified. Or if we think it will be profitable.
-    if (L->isLoopExiting(OrigLatch) && !SimplifiedLatch && IsUtilMode == false &&
-        !profitableToRotateLoopExitingLatch(L) &&
-        !canRotateDeoptimizingLatchExit(L))
+    }
+    if (!Metrics.NumInsts.isValid()) {
+      LLVM_DEBUG(dbgs() << "LoopRotation: NOT rotating - contains instructions"
+                  " with invalid cost: ";
+                  L->dump());
       return Rotated;
-
-    // Check size of original header and reject loop if it is very big or we can't
-    // duplicate blocks inside it.
-    {
-      SmallPtrSet<const Value *, 32> EphValues;
-      CodeMetrics::collectEphemeralValues(L, AC, EphValues);
-
-      CodeMetrics Metrics;
-      Metrics.analyzeBasicBlock(OrigHeader, *TTI, EphValues, PrepareForLTO);
-      if (Metrics.notDuplicatable) {
-        LLVM_DEBUG(
-                   dbgs() << "LoopRotation: NOT rotating - contains non-duplicatable"
-                   << " instructions: ";
-                   L->dump());
-        return Rotated;
-      }
-      if (Metrics.Convergence != ConvergenceKind::None) {
-        LLVM_DEBUG(dbgs() << "LoopRotation: NOT rotating - contains convergent "
-                   "instructions: ";
-                   L->dump());
-        return Rotated;
-      }
-      if (!Metrics.NumInsts.isValid()) {
-        LLVM_DEBUG(dbgs() << "LoopRotation: NOT rotating - contains instructions"
-                   " with invalid cost: ";
-                   L->dump());
-        return Rotated;
-      }
-      if (Metrics.NumInsts > MaxHeaderSize) {
-        LLVM_DEBUG(dbgs() << "LoopRotation: NOT rotating - contains "
-                          << Metrics.NumInsts
-                          << " instructions, which is more than the threshold ("
-                          << MaxHeaderSize << " instructions): ";
-                   L->dump());
-        ++NumNotRotatedDueToHeaderSize;
-        return Rotated;
-      }
-
-      // When preparing for LTO, avoid rotating loops with calls that could be
-      // inlined during the LTO stage.
-      if (PrepareForLTO && Metrics.NumInlineCandidates > 0)
-        return Rotated;
     }
-
-    // Now, this loop is suitable for rotation.
-    BasicBlock *OrigPreheader = L->getLoopPreheader();
-
-    // If the loop could not be converted to canonical form, it must have an
-    // indirectbr in it, just give up.
-    if (!OrigPreheader || !L->hasDedicatedExits())
+    if (Metrics.NumInsts > MaxHeaderSize) {
+      LLVM_DEBUG(dbgs() << "LoopRotation: NOT rotating - contains "
+                        << Metrics.NumInsts
+                        << " instructions, which is more than the threshold ("
+                        << MaxHeaderSize << " instructions): ";
+                  L->dump());
+      ++NumNotRotatedDueToHeaderSize;
       return Rotated;
-
-    // Anything ScalarEvolution may know about this loop or the PHI nodes
-    // in its header will soon be invalidated. We should also invalidate
-    // all outer loops because insertion and deletion of blocks that happens
-    // during the rotation may violate invariants related to backedge taken
-    // infos in them.
-    if (SE) {
-      SE->forgetTopmostLoop(L);
-      // We may hoist some instructions out of loop. In case if they were cached
-      // as "loop variant" or "loop computable", these caches must be dropped.
-      // We also may fold basic blocks, so cached block dispositions also need
-      // to be dropped.
-      SE->forgetBlockAndLoopDispositions();
     }
 
-    LLVM_DEBUG(dbgs() << "LoopRotation: rotating "; L->dump());
-    if (MSSAU && VerifyMemorySSA)
-      MSSAU->getMemorySSA()->verifyMemorySSA();
-
-    // Find new Loop header. NewHeader is a Header's one and only successor
-    // that is inside loop.  Header's other successor is outside the
-    // loop.  Otherwise loop is not suitable for rotation.
-    BasicBlock *Exit = BI->getSuccessor(0);
-    BasicBlock *NewHeader = BI->getSuccessor(1);
-    bool BISuccsSwapped = L->contains(Exit);
-    if (BISuccsSwapped)
-      std::swap(Exit, NewHeader);
-    assert(NewHeader && "Unable to determine new loop header");
-    assert(L->contains(NewHeader) && !L->contains(Exit) &&
-           "Unable to determine loop header and exit blocks");
-
-    // This code assumes that the new header has exactly one predecessor.
-    // Remove any single-entry PHI nodes in it.
-    assert(NewHeader->getSinglePredecessor() &&
-           "New header doesn't have one pred!");
-    FoldSingleEntryPHINodes(NewHeader);
-
-    // Begin by walking OrigHeader and populating ValueMap with an entry for
-    // each Instruction.
-    BasicBlock::iterator I = OrigHeader->begin(), E = OrigHeader->end();
-    ValueToValueMapTy ValueMap, ValueMapMSSA;
-
-    // For PHI nodes, the value available in OldPreHeader is just the
-    // incoming value from OldPreHeader.
-    for (; PHINode *PN = dyn_cast<PHINode>(I); ++I)
-      InsertNewValueIntoMap(ValueMap, PN,
-                            PN->getIncomingValueForBlock(OrigPreheader));
-
-    // For the rest of the instructions, either hoist to the OrigPreheader if
-    // possible or create a clone in the OldPreHeader if not.
-    Instruction *LoopEntryBranch = OrigPreheader->getTerminator();
-
-    // Record all debug records preceding LoopEntryBranch to avoid
-    // duplication.
-    using DbgHash =
-        std::pair<std::pair<hash_code, DILocalVariable *>, DIExpression *>;
-    auto makeHash = [](const DbgVariableRecord *D) -> DbgHash {
-      auto VarLocOps = D->location_ops();
-      return {{hash_combine_range(VarLocOps), D->getVariable()},
-              D->getExpression()};
-    };
-
-    SmallDenseSet<DbgHash, 8> DbgRecords;
-    // Build DbgVariableRecord hashes for DbgVariableRecords attached to the
-    // terminator.
-    for (const DbgVariableRecord &DVR :
-         filterDbgVars(OrigPreheader->getTerminator()->getDbgRecordRange()))
-      DbgRecords.insert(makeHash(&DVR));
-
-    // Remember the local noalias scope declarations in the header. After the
-    // rotation, they must be duplicated and the scope must be cloned. This
-    // avoids unwanted interaction across iterations.
-    SmallVector<NoAliasScopeDeclInst *, 6> NoAliasDeclInstructions;
-    for (Instruction &I : *OrigHeader)
-      if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
-        NoAliasDeclInstructions.push_back(Decl);
-
-    Module *M = OrigHeader->getModule();
-
-    // Track the next DbgRecord to clone. If we have a sequence where an
-    // instruction is hoisted instead of being cloned:
-    //    DbgRecord blah
-    //    %foo = add i32 0, 0
-    //    DbgRecord xyzzy
-    //    %bar = call i32 @foobar()
-    // where %foo is hoisted, then the DbgRecord "blah" will be seen twice, once
-    // attached to %foo, then when %foo his hoisted it will "fall down" onto the
-    // function call:
-    //    DbgRecord blah
-    //    DbgRecord xyzzy
-    //    %bar = call i32 @foobar()
-    // causing it to appear attached to the call too.
-    //
-    // To avoid this, cloneDebugInfoFrom takes an optional "start cloning from
-    // here" position to account for this behaviour. We point it at any
-    // DbgRecords on the next instruction, here labelled xyzzy, before we hoist
-    // %foo. Later, we only only clone DbgRecords from that position (xyzzy)
-    // onwards, which avoids cloning DbgRecord "blah" multiple times. (Stored as
-    // a range because it gives us a natural way of testing whether
-    //  there were DbgRecords on the next instruction before we hoisted things).
-    iterator_range<DbgRecord::self_iterator> NextDbgInsts =
-        (I != E) ? I->getDbgRecordRange() : DbgMarker::getEmptyDbgRecordRange();
-
-    while (I != E) {
-      Instruction *Inst = &*I++;
-
-      // If the instruction's operands are invariant and it doesn't read or write
-      // memory, then it is safe to hoist.  Doing this doesn't change the order of
-      // execution in the preheader, but does prevent the instruction from
-      // executing in each iteration of the loop.  This means it is safe to hoist
-      // something that might trap, but isn't safe to hoist something that reads
-      // memory (without proving that the loop doesn't write).
-      if (L->hasLoopInvariantOperands(Inst) && !Inst->mayReadFromMemory() &&
-          !Inst->mayWriteToMemory() && !Inst->isTerminator() &&
-          !isa<AllocaInst>(Inst) &&
-          // It is not safe to hoist the value of these instructions in
-          // coroutines, as the addresses of otherwise eligible variables (e.g.
-          // thread-local variables and errno) may change if the coroutine is
-          // resumed in a different thread.Therefore, we disable this
-          // optimization for correctness. However, this may block other correct
-          // optimizations.
-          // FIXME: This should be reverted once we have a better model for
-          // memory access in coroutines.
-          !Inst->getFunction()->isPresplitCoroutine()) {
-
-        if (!NextDbgInsts.empty()) {
-          auto DbgValueRange =
-              LoopEntryBranch->cloneDebugInfoFrom(Inst, NextDbgInsts.begin());
-          RemapDbgRecordRange(M, DbgValueRange, ValueMap,
-                              RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
-          // Erase anything we've seen before.
-          for (DbgVariableRecord &DVR :
-               make_early_inc_range(filterDbgVars(DbgValueRange)))
-            if (DbgRecords.count(makeHash(&DVR)))
-              DVR.eraseFromParent();
-        }
-
-        NextDbgInsts = I->getDbgRecordRange();
-
-        Inst->moveBefore(LoopEntryBranch->getIterator());
+    // When preparing for LTO, avoid rotating loops with calls that could be
+    // inlined during the LTO stage.
+    if (PrepareForLTO && Metrics.NumInlineCandidates > 0)
+      return Rotated;
+  }
 
-        ++NumInstrsHoisted;
-        continue;
-      }
+  // Now, this loop is suitable for rotation.
+  BasicBlock *OrigPreheader = L->getLoopPreheader();
+
+  // If the loop could not be converted to canonical form, it must have an
+  // indirectbr in it, just give up.
+  if (!OrigPreheader || !L->hasDedicatedExits())
+    return Rotated;
+
+  // Anything ScalarEvolution may know about this loop or the PHI nodes
+  // in its header will soon be invalidated. We should also invalidate
+  // all outer loops because insertion and deletion of blocks that happens
+  // during the rotation may violate invariants related to backedge taken
+  // infos in them.
+  if (SE) {
+    SE->forgetTopmostLoop(L);
+    // We may hoist some instructions out of loop. In case if they were cached
+    // as "loop variant" or "loop computable", these caches must be dropped.
+    // We also may fold basic blocks, so cached block dispositions also need
+    // to be dropped.
+    SE->forgetBlockAndLoopDispositions();
+  }
 
-      // Otherwise, create a duplicate of the instruction.
-      Instruction *C = Inst->clone();
-      if (const DebugLoc &DL = C->getDebugLoc())
-        mapAtomInstance(DL, ValueMap);
+  LLVM_DEBUG(dbgs() << "LoopRotation: rotating "; L->dump());
+  if (MSSAU && VerifyMemorySSA)
+    MSSAU->getMemorySSA()->verifyMemorySSA();
 
-      C->insertBefore(LoopEntryBranch->getIterator());
+  // Find new Loop header. NewHeader is a Header's one and only successor
+  // that is inside loop.  Header's other successor is outside the
+  // loop.  Otherwise loop is not suitable for rotation.
+  BasicBlock *Exit = BI->getSuccessor(0);
+  BasicBlock *NewHeader = BI->getSuccessor(1);
+  bool BISuccsSwapped = L->contains(Exit);
+  if (BISuccsSwapped)
+    std::swap(Exit, NewHeader);
+  assert(NewHeader && "Unable to determine new loop header");
+  assert(L->contains(NewHeader) && !L->contains(Exit) &&
+          "Unable to determine loop header and exit blocks");
+
+  // This code assumes that the new header has exactly one predecessor.
+  // Remove any single-entry PHI nodes in it.
+  assert(NewHeader->getSinglePredecessor() &&
+          "New header doesn't have one pred!");
+  FoldSingleEntryPHINodes(NewHeader);
+
+  // Begin by walking OrigHeader and populating ValueMap with an entry for
+  // each Instruction.
+  BasicBlock::iterator I = OrigHeader->begin(), E = OrigHeader->end();
+  ValueToValueMapTy ValueMap, ValueMapMSSA;
+
+  // For PHI nodes, the value available in OldPreHeader is just the
+  // incoming value from OldPreHeader.
+  for (; PHINode *PN = dyn_cast<PHINode>(I); ++I)
+    InsertNewValueIntoMap(ValueMap, PN,
+                          PN->getIncomingValueForBlock(OrigPreheader));
+
+  // For the rest of the instructions, either hoist to the OrigPreheader if
+  // possible or create a clone in the OldPreHeader if not.
+  Instruction *LoopEntryBranch = OrigPreheader->getTerminator();
+
+  // Record all debug records preceding LoopEntryBranch to avoid
+  // duplication.
+  using DbgHash =
+      std::pair<std::pair<hash_code, DILocalVariable *>, DIExpression *>;
+  auto makeHash = [](const DbgVariableRecord *D) -> DbgHash {
+    auto VarLocOps = D->location_ops();
+    return {{hash_combine_range(VarLocOps), D->getVariable()},
+            D->getExpression()};
+  };
 
-      ++NumInstrsDuplicated;
+  SmallDenseSet<DbgHash, 8> DbgRecords;
+  // Build DbgVariableRecord hashes for DbgVariableRecords attached to the
+  // terminator.
+  for (const DbgVariableRecord &DVR :
+        filterDbgVars(OrigPreheader->getTerminator()->getDbgRecordRange()))
+    DbgRecords.insert(makeHash(&DVR));
+
+  // Remember the local noalias scope declarations in the header. After the
+  // rotation, they must be duplicated and the scope must be cloned. This
+  // avoids unwanted interaction across iterations.
+  SmallVector<NoAliasScopeDeclInst *, 6> NoAliasDeclInstructions;
+  for (Instruction &I : *OrigHeader)
+    if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
+      NoAliasDeclInstructions.push_back(Decl);
+
+  Module *M = OrigHeader->getModule();
+
+  // Track the next DbgRecord to clone. If we have a sequence where an
+  // instruction is hoisted instead of being cloned:
+  //    DbgRecord blah
+  //    %foo = add i32 0, 0
+  //    DbgRecord xyzzy
+  //    %bar = call i32 @foobar()
+  // where %foo is hoisted, then the DbgRecord "blah" will be seen twice, once
+  // attached to %foo, then when %foo his hoisted it will "fall down" onto the
+  // function call:
+  //    DbgRecord blah
+  //    DbgRecord xyzzy
+  //    %bar = call i32 @foobar()
+  // causing it to appear attached to the call too.
+  //
+  // To avoid this, cloneDebugInfoFrom takes an optional "start cloning from
+  // here" position to account for this behaviour. We point it at any
+  // DbgRecords on the next instruction, here labelled xyzzy, before we hoist
+  // %foo. Later, we only only clone DbgRecords from that position (xyzzy)
+  // onwards, which avoids cloning DbgRecord "blah" multiple times. (Stored as
+  // a range because it gives us a natural way of testing whether
+  //  there were DbgRecords on the next instruction before we hoisted things).
+  iterator_range<DbgRecord::self_iterator> NextDbgInsts =
+      (I != E) ? I->getDbgRecordRange() : DbgMarker::getEmptyDbgRecordRange();
+
+  while (I != E) {
+    Instruction *Inst = &*I++;
+
+    // If the instruction's operands are invariant and it doesn't read or write
+    // memory, then it is safe to hoist.  Doing this doesn't change the order of
+    // execution in the preheader, but does prevent the instruction from
+    // executing in each iteration of the loop.  This means it is safe to hoist
+    // something that might trap, but isn't safe to hoist something that reads
+    // memory (without proving that the loop doesn't write).
+    if (L->hasLoopInvariantOperands(Inst) && !Inst->mayReadFromMemory() &&
+        !Inst->mayWriteToMemory() && !Inst->isTerminator() &&
+        !isa<AllocaInst>(Inst) &&
+        // It is not safe to hoist the value of these instructions in
+        // coroutines, as the addresses of otherwise eligible variables (e.g.
+        // thread-local variables and errno) may change if the coroutine is
+        // resumed in a different thread.Therefore, we disable this
+        // optimization for correctness. However, this may block other correct
+        // optimizations.
+        // FIXME: This should be reverted once we have a better model for
+        // memory access in coroutines.
+        !Inst->getFunction()->isPresplitCoroutine()) {
 
       if (!NextDbgInsts.empty()) {
-        auto Range = C->cloneDebugInfoFrom(Inst, NextDbgInsts.begin());
-        RemapDbgRecordRange(M, Range, ValueMap,
+        auto DbgValueRange =
+            LoopEntryBranch->cloneDebugInfoFrom(Inst, NextDbgInsts.begin());
+        RemapDbgRecordRange(M, DbgValueRange, ValueMap,
                             RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
-        NextDbgInsts = DbgMarker::getEmptyDbgRecordRange();
         // Erase anything we've seen before.
         for (DbgVariableRecord &DVR :
-             make_early_inc_range(filterDbgVars(Range)))
+              make_early_inc_range(filterDbgVars(DbgValueRange)))
           if (DbgRecords.count(makeHash(&DVR)))
             DVR.eraseFromParent();
       }
 
-      // Eagerly remap the operands of the instruction.
-      RemapInstruction(C, ValueMap,
-                       RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
-
-      // With the operands remapped, see if the instruction constant folds or is
-      // otherwise simplifyable.  This commonly occurs because the entry from PHI
-      // nodes allows icmps and other instructions to fold.
-      Value *V = simplifyInstruction(C, SQ);
-      if (V && LI->replacementPreservesLCSSAForm(C, V)) {
-        // If so, then delete the temporary instruction and stick the folded value
-        // in the map.
-        InsertNewValueIntoMap(ValueMap, Inst, V);
-        if (!C->mayHaveSideEffects()) {
-          C->eraseFromParent();
-          C = nullptr;
-        }
-      } else {
-        InsertNewValueIntoMap(ValueMap, Inst, C);
-      }
-      if (C) {
-        // Otherwise, stick the new instruction into the new block!
-        C->setName(Inst->getName());
-
-        if (auto *II = dyn_cast<AssumeInst>(C))
-          AC->registerAssumption(II);
-        // MemorySSA cares whether the cloned instruction was inserted or not, and
-        // not whether it can be remapped to a simplified value.
-        if (MSSAU)
-          InsertNewValueIntoMap(ValueMapMSSA, Inst, C);
-      }
-    }
+      NextDbgInsts = I->getDbgRecordRange();
 
-    if (!NoAliasDeclInstructions.empty()) {
-      // There are noalias scope declarations:
-      // (general):
-      // Original:    OrigPre              { OrigHeader NewHeader ... Latch }
-      // after:      (OrigPre+OrigHeader') { NewHeader ... Latch OrigHeader }
-      //
-      // with D: llvm.experimental.noalias.scope.decl,
-      //      U: !noalias or !alias.scope depending on D
-      //       ... { D U1 U2 }   can transform into:
-      // (0) : ... { D U1 U2 }        // no relevant rotation for this part
-      // (1) : ... D' { U1 U2 D }     // D is part of OrigHeader
-      // (2) : ... D' U1' { U2 D U1 } // D, U1 are part of OrigHeader
-      //
-      // We now want to transform:
-      // (1) -> : ... D' { D U1 U2 D'' }
-      // (2) -> : ... D' U1' { D U2 D'' U1'' }
-      // D: original llvm.experimental.noalias.scope.decl
-      // D', U1': duplicate with replaced scopes
-      // D'', U1'': different duplicate with replaced scopes
-      // This ensures a safe fallback to 'may_alias' introduced by the rotate,
-      // as U1'' and U1' scopes will not be compatible wrt to the local restrict
-
-      // Clone the llvm.experimental.noalias.decl again for the NewHeader.
-      BasicBlock::iterator NewHeaderInsertionPoint =
-          NewHeader->getFirstNonPHIIt();
-      for (NoAliasScopeDeclInst *NAD : NoAliasDeclInstructions) {
-        LLVM_DEBUG(dbgs() << "  Cloning llvm.experimental.noalias.scope.decl:"
-                          << *NAD << "\n");
-        Instruction *NewNAD = NAD->clone();
-        NewNAD->insertBefore(*NewHeader, NewHeaderInsertionPoint);
-      }
+      Inst->moveBefore(LoopEntryBranch->getIterator());
 
-      // Scopes must now be duplicated, once for OrigHeader and once for
-      // OrigPreHeader'.
-      {
-        auto &Context = NewHeader->getContext();
-
-        SmallVector<MDNode *, 8> NoAliasDeclScopes;
-        for (NoAliasScopeDeclInst *NAD : NoAliasDeclInstructions)
-          NoAliasDeclScopes.push_back(NAD->getScopeList());
-
-        LLVM_DEBUG(dbgs() << "  Updating OrigHeader scopes\n");
-        cloneAndAdaptNoAliasScopes(NoAliasDeclScopes, {OrigHeader}, Context,
-                                   "h.rot");
-        LLVM_DEBUG(OrigHeader->dump());
-
-        // Keep the compile time impact low by only adapting the inserted block
-        // of instructions in the OrigPreHeader. This might result in slightly
-        // more aliasing between these instructions and those that were already
-        // present, but it will be much faster when the original PreHeader is
-        // large.
-        LLVM_DEBUG(dbgs() << "  Updating part of OrigPreheader scopes\n");
-        auto *FirstDecl =
-            cast<Instruction>(ValueMap[*NoAliasDeclInstructions.begin()]);
-        auto *LastInst = &OrigPreheader->back();
-        cloneAndAdaptNoAliasScopes(NoAliasDeclScopes, FirstDecl, LastInst,
-                                   Context, "pre.rot");
-        LLVM_DEBUG(OrigPreheader->dump());
-
-        LLVM_DEBUG(dbgs() << "  Updated NewHeader:\n");
-        LLVM_DEBUG(NewHeader->dump());
-      }
-    }
-
-    // Along with all the other instructions, we just cloned OrigHeader's
-    // terminator into OrigPreHeader. Fix up the PHI nodes in each of OrigHeader's
-    // successors by duplicating their incoming values for OrigHeader.
-    for (BasicBlock *SuccBB : successors(OrigHeader))
-      for (BasicBlock::iterator BI = SuccBB->begin();
-           PHINode *PN = dyn_cast<PHINode>(BI); ++BI)
-        PN->addIncoming(PN->getIncomingValueForBlock(OrigHeader), OrigPreheader);
-
-    // Now that OrigPreHeader has a clone of OrigHeader's terminator, remove
-    // OrigPreHeader's old terminator (the original branch into the loop), and
-    // remove the corresponding incoming values from the PHI nodes in OrigHeader.
-    LoopEntryBranch->eraseFromParent();
-    OrigPreheader->flushTerminatorDbgRecords();
-
-    // Update MemorySSA before the rewrite call below changes the 1:1
-    // instruction:cloned_instruction_or_value mapping.
-    if (MSSAU) {
-      InsertNewValueIntoMap(ValueMapMSSA, OrigHeader, OrigPreheader);
-      MSSAU->updateForClonedBlockIntoPred(OrigHeader, OrigPreheader,
-                                          ValueMapMSSA);
+      ++NumInstrsHoisted;
+      continue;
     }
 
-    SmallVector<PHINode*, 2> InsertedPHIs;
-    // If there were any uses of instructions in the duplicated block outside the
-    // loop, update them, inserting PHI nodes as required
-    RewriteUsesOfClonedInstructions(OrigHeader, OrigPreheader, ValueMap, SE,
-                                    &InsertedPHIs);
-
-    // Attach debug records to the new phis if that phi uses a value that
-    // previously had debug metadata attached. This keeps the debug info
-    // up-to-date in the loop body.
-    if (!InsertedPHIs.empty())
-      insertDebugValuesForPHIs(OrigHeader, InsertedPHIs);
-
-    // NewHeader is now the header of the loop.
-    L->moveToHeader(NewHeader);
-    assert(L->getHeader() == NewHeader && "Latch block is our new header");
-
-    // Inform DT about changes to the CFG.
-    if (DT) {
-      // The OrigPreheader branches to the NewHeader and Exit now. Then, inform
-      // the DT about the removed edge to the OrigHeader (that got removed).
-      SmallVector<DominatorTree::UpdateType, 3> Updates = {
-          {DominatorTree::Insert, OrigPreheader, Exit},
-          {DominatorTree::Insert, OrigPreheader, NewHeader},
-          {DominatorTree::Delete, OrigPreheader, OrigHeader}};
-
-      if (MSSAU) {
-        MSSAU->applyUpdates(Updates, *DT, /*UpdateDT=*/true);
-        if (VerifyMemorySSA)
-          MSSAU->getMemorySSA()->verifyMemorySSA();
-      } else {
-        DT->applyUpdates(Updates);
-      }
+    // Otherwise, create a duplicate of the instruction.
+    Instruction *C = Inst->clone();
+    if (const DebugLoc &DL = C->getDebugLoc())
+      mapAtomInstance(DL, ValueMap);
+
+    C->insertBefore(LoopEntryBranch->getIterator());
+
+    ++NumInstrsDuplicated;
+
+    if (!NextDbgInsts.empty()) {
+      auto Range = C->cloneDebugInfoFrom(Inst, NextDbgInsts.begin());
+      RemapDbgRecordRange(M, Range, ValueMap,
+                          RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
+      NextDbgInsts = DbgMarker::getEmptyDbgRecordRange();
+      // Erase anything we've seen before.
+      for (DbgVariableRecord &DVR :
+            make_early_inc_range(filterDbgVars(Range)))
+        if (DbgRecords.count(makeHash(&DVR)))
+          DVR.eraseFromParent();
     }
 
-    // At this point, we've finished our major CFG changes.  As part of cloning
-    // the loop into the preheader we've simplified instructions and the
-    // duplicated conditional branch may now be branching on a constant.  If it is
-    // branching on a constant and if that constant means that we enter the loop,
-    // then we fold away the cond branch to an uncond branch.  This simplifies the
-    // loop in cases important for nested loops, and it also means we don't have
-    // to split as many edges.
-    BranchInst *PHBI = cast<BranchInst>(OrigPreheader->getTerminator());
-    assert(PHBI->isConditional() && "Should be clone of BI condbr!");
-    const Value *Cond = PHBI->getCondition();
-    const bool HasConditionalPreHeader =
-        !isa<ConstantInt>(Cond) ||
-        PHBI->getSuccessor(cast<ConstantInt>(Cond)->isZero()) != NewHeader;
-
-    updateBranchWeights(*PHBI, *BI, HasConditionalPreHeader, BISuccsSwapped);
-
-    if (HasConditionalPreHeader) {
-      // The conditional branch can't be folded, handle the general case.
-      // Split edges as necessary to preserve LoopSimplify form.
-
-      // Right now OrigPreHeader has two successors, NewHeader and ExitBlock, and
-      // thus is not a preheader anymore.
-      // Split the edge to form a real preheader.
-      BasicBlock *NewPH = SplitCriticalEdge(
-                                            OrigPreheader, NewHeader,
-                                            CriticalEdgeSplittingOptions(DT, LI, MSSAU).setPreserveLCSSA());
-      NewPH->setName(NewHeader->getName() + ".lr.ph");
-
-      // Preserve canonical loop form, which means that 'Exit' should have only
-      // one predecessor. Note that Exit could be an exit block for multiple
-      // nested loops, causing both of the edges to now be critical and need to
-      // be split.
-      SmallVector<BasicBlock *, 4> ExitPreds(predecessors(Exit));
-      bool SplitLatchEdge = false;
-      for (BasicBlock *ExitPred : ExitPreds) {
-        // We only need to split loop exit edges.
-        Loop *PredLoop = LI->getLoopFor(ExitPred);
-        if (!PredLoop || PredLoop->contains(Exit) ||
-            isa<IndirectBrInst>(ExitPred->getTerminator()))
-          continue;
-        SplitLatchEdge |= L->getLoopLatch() == ExitPred;
-        BasicBlock *ExitSplit = SplitCriticalEdge(
-                                                  ExitPred, Exit,
-                                                  CriticalEdgeSplittingOptions(DT, LI, MSSAU).setPreserveLCSSA());
-        ExitSplit->moveBefore(Exit);
+    // Eagerly remap the operands of the instruction.
+    RemapInstruction(C, ValueMap,
+                      RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
+
+    // With the operands remapped, see if the instruction constant folds or is
+    // otherwise simplifyable.  This commonly occurs because the entry from PHI
+    // nodes allows icmps and other instructions to fold.
+    Value *V = simplifyInstruction(C, SQ);
+    if (V && LI->replacementPreservesLCSSAForm(C, V)) {
+      // If so, then delete the temporary instruction and stick the folded value
+      // in the map.
+      InsertNewValueIntoMap(ValueMap, Inst, V);
+      if (!C->mayHaveSideEffects()) {
+        C->eraseFromParent();
+        C = nullptr;
       }
-      assert(SplitLatchEdge &&
-             "Despite splitting all preds, failed to split latch exit?");
-      (void)SplitLatchEdge;
     } else {
-      // We can fold the conditional branch in the preheader, this makes things
-      // simpler. The first step is to remove the extra edge to the Exit block.
-      Exit->removePredecessor(OrigPreheader, true /*preserve LCSSA*/);
-      BranchInst *NewBI = BranchInst::Create(NewHeader, PHBI->getIterator());
-      NewBI->setDebugLoc(PHBI->getDebugLoc());
-      PHBI->eraseFromParent();
+      InsertNewValueIntoMap(ValueMap, Inst, C);
+    }
+    if (C) {
+      // Otherwise, stick the new instruction into the new block!
+      C->setName(Inst->getName());
+
+      if (auto *II = dyn_cast<AssumeInst>(C))
+        AC->registerAssumption(II);
+      // MemorySSA cares whether the cloned instruction was inserted or not, and
+      // not whether it can be remapped to a simplified value.
+      if (MSSAU)
+        InsertNewValueIntoMap(ValueMapMSSA, Inst, C);
+    }
+  }
 
-      // With our CFG finalized, update DomTree if it is available.
-      if (DT) DT->deleteEdge(OrigPreheader, Exit);
+  if (!NoAliasDeclInstructions.empty()) {
+    // There are noalias scope declarations:
+    // (general):
+    // Original:    OrigPre              { OrigHeader NewHeader ... Latch }
+    // after:      (OrigPre+OrigHeader') { NewHeader ... Latch OrigHeader }
+    //
+    // with D: llvm.experimental.noalias.scope.decl,
+    //      U: !noalias or !alias.scope depending on D
+    //       ... { D U1 U2 }   can transform into:
+    // (0) : ... { D U1 U2 }        // no relevant rotation for this part
+    // (1) : ... D' { U1 U2 D }     // D is part of OrigHeader
+    // (2) : ... D' U1' { U2 D U1 } // D, U1 are part of OrigHeader
+    //
+    // We now want to transform:
+    // (1) -> : ... D' { D U1 U2 D'' }
+    // (2) -> : ... D' U1' { D U2 D'' U1'' }
+    // D: original llvm.experimental.noalias.scope.decl
+    // D', U1': duplicate with replaced scopes
+    // D'', U1'': different duplicate with replaced scopes
+    // This ensures a safe fallback to 'may_alias' introduced by the rotate,
+    // as U1'' and U1' scopes will not be compatible wrt to the local restrict
+
+    // Clone the llvm.experimental.noalias.decl again for the NewHeader.
+    BasicBlock::iterator NewHeaderInsertionPoint =
+        NewHeader->getFirstNonPHIIt();
+    for (NoAliasScopeDeclInst *NAD : NoAliasDeclInstructions) {
+      LLVM_DEBUG(dbgs() << "  Cloning llvm.experimental.noalias.scope.decl:"
+                        << *NAD << "\n");
+      Instruction *NewNAD = NAD->clone();
+      NewNAD->insertBefore(*NewHeader, NewHeaderInsertionPoint);
+    }
 
-      // Update MSSA too, if available.
-      if (MSSAU)
-        MSSAU->removeEdge(OrigPreheader, Exit);
+    // Scopes must now be duplicated, once for OrigHeader and once for
+    // OrigPreHeader'.
+    {
+      auto &Context = NewHeader->getContext();
+
+      SmallVector<MDNode *, 8> NoAliasDeclScopes;
+      for (NoAliasScopeDeclInst *NAD : NoAliasDeclInstructions)
+        NoAliasDeclScopes.push_back(NAD->getScopeList());
+
+      LLVM_DEBUG(dbgs() << "  Updating OrigHeader scopes\n");
+      cloneAndAdaptNoAliasScopes(NoAliasDeclScopes, {OrigHeader}, Context,
+                                  "h.rot");
+      LLVM_DEBUG(OrigHeader->dump());
+
+      // Keep the compile time impact low by only adapting the inserted block
+      // of instructions in the OrigPreHeader. This might result in slightly
+      // more aliasing between these instructions and those that were already
+      // present, but it will be much faster when the original PreHeader is
+      // large.
+      LLVM_DEBUG(dbgs() << "  Updating part of OrigPreheader scopes\n");
+      auto *FirstDecl =
+          cast<Instruction>(ValueMap[*NoAliasDeclInstructions.begin()]);
+      auto *LastInst = &OrigPreheader->back();
+      cloneAndAdaptNoAliasScopes(NoAliasDeclScopes, FirstDecl, LastInst,
+                                  Context, "pre.rot");
+      LLVM_DEBUG(OrigPreheader->dump());
+
+      LLVM_DEBUG(dbgs() << "  Updated NewHeader:\n");
+      LLVM_DEBUG(NewHeader->dump());
     }
+  }
 
-    assert(L->getLoopPreheader() && "Invalid loop preheader after loop rotation");
-    assert(L->getLoopLatch() && "Invalid loop latch after loop rotation");
+  // Along with all the other instructions, we just cloned OrigHeader's
+  // terminator into OrigPreHeader. Fix up the PHI nodes in each of OrigHeader's
+  // successors by duplicating their incoming values for OrigHeader.
+  for (BasicBlock *SuccBB : successors(OrigHeader))
+    for (BasicBlock::iterator BI = SuccBB->begin();
+          PHINode *PN = dyn_cast<PHINode>(BI); ++BI)
+      PN->addIncoming(PN->getIncomingValueForBlock(OrigHeader), OrigPreheader);
+
+  // Now that OrigPreHeader has a clone of OrigHeader's terminator, remove
+  // OrigPreHeader's old terminator (the original branch into the loop), and
+  // remove the corresponding incoming values from the PHI nodes in OrigHeader.
+  LoopEntryBranch->eraseFromParent();
+  OrigPreheader->flushTerminatorDbgRecords();
+
+  // Update MemorySSA before the rewrite call below changes the 1:1
+  // instruction:cloned_instruction_or_value mapping.
+  if (MSSAU) {
+    InsertNewValueIntoMap(ValueMapMSSA, OrigHeader, OrigPreheader);
+    MSSAU->updateForClonedBlockIntoPred(OrigHeader, OrigPreheader,
+                                        ValueMapMSSA);
+  }
 
-    if (MSSAU && VerifyMemorySSA)
-      MSSAU->getMemorySSA()->verifyMemorySSA();
+  SmallVector<PHINode*, 2> InsertedPHIs;
+  // If there were any uses of instructions in the duplicated block outside the
+  // loop, update them, inserting PHI nodes as required
+  RewriteUsesOfClonedInstructions(OrigHeader, OrigPreheader, ValueMap, SE,
+                                  &InsertedPHIs);
+
+  // Attach debug records to the new phis if that phi uses a value that
+  // previously had debug metadata attached. This keeps the debug info
+  // up-to-date in the loop body.
+  if (!InsertedPHIs.empty())
+    insertDebugValuesForPHIs(OrigHeader, InsertedPHIs);
+
+  // NewHeader is now the header of the loop.
+  L->moveToHeader(NewHeader);
+  assert(L->getHeader() == NewHeader && "Latch block is our new header");
+
+  // Inform DT about changes to the CFG.
+  if (DT) {
+    // The OrigPreheader branches to the NewHeader and Exit now. Then, inform
+    // the DT about the removed edge to the OrigHeader (that got removed).
+    SmallVector<DominatorTree::UpdateType, 3> Updates = {
+        {DominatorTree::Insert, OrigPreheader, Exit},
+        {DominatorTree::Insert, OrigPreheader, NewHeader},
+        {DominatorTree::Delete, OrigPreheader, OrigHeader}};
 
-    // Now that the CFG and DomTree are in a consistent state again, try to merge
-    // the OrigHeader block into OrigLatch.  This will succeed if they are
-    // connected by an unconditional branch.  This is just a cleanup so the
-    // emitted code isn't too gross in this common case.
-    DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
-    BasicBlock *PredBB = OrigHeader->getUniquePredecessor();
-    bool DidMerge = MergeBlockIntoPredecessor(OrigHeader, &DTU, LI, MSSAU);
-    if (DidMerge)
-      RemoveRedundantDbgInstrs(PredBB);
+    if (MSSAU) {
+      MSSAU->applyUpdates(Updates, *DT, /*UpdateDT=*/true);
+      if (VerifyMemorySSA)
+        MSSAU->getMemorySSA()->verifyMemorySSA();
+    } else {
+      DT->applyUpdates(Updates);
+    }
+  }
 
-    if (MSSAU && VerifyMemorySSA)
-      MSSAU->getMemorySSA()->verifyMemorySSA();
+  // At this point, we've finished our major CFG changes.  As part of cloning
+  // the loop into the preheader we've simplified instructions and the
+  // duplicated conditional branch may now be branching on a constant.  If it is
+  // branching on a constant and if that constant means that we enter the loop,
+  // then we fold away the cond branch to an uncond branch.  This simplifies the
+  // loop in cases important for nested loops, and it also means we don't have
+  // to split as many edges.
+  BranchInst *PHBI = cast<BranchInst>(OrigPreheader->getTerminator());
+  assert(PHBI->isConditional() && "Should be clone of BI condbr!");
+  const Value *Cond = PHBI->getCondition();
+  const bool HasConditionalPreHeader =
+      !isa<ConstantInt>(Cond) ||
+      PHBI->getSuccessor(cast<ConstantInt>(Cond)->isZero()) != NewHeader;
+
+  updateBranchWeights(*PHBI, *BI, HasConditionalPreHeader, BISuccsSwapped);
 
-    LLVM_DEBUG(dbgs() << "LoopRotation: into "; L->dump());
+  if (HasConditionalPreHeader) {
+    // The conditional branch can't be folded, handle the general case.
+    // Split edges as necessary to preserve LoopSimplify form.
+
+    // Right now OrigPreHeader has two successors, NewHeader and ExitBlock, and
+    // thus is not a preheader anymore.
+    // Split the edge to form a real preheader.
+    BasicBlock *NewPH = SplitCriticalEdge(
+                                          OrigPreheader, NewHeader,
+                                          CriticalEdgeSplittingOptions(DT, LI, MSSAU).setPreserveLCSSA());
+    NewPH->setName(NewHeader->getName() + ".lr.ph");
+
+    // Preserve canonical loop form, which means that 'Exit' should have only
+    // one predecessor. Note that Exit could be an exit block for multiple
+    // nested loops, causing both of the edges to now be critical and need to
+    // be split.
+    SmallVector<BasicBlock *, 4> ExitPreds(predecessors(Exit));
+    bool SplitLatchEdge = false;
+    for (BasicBlock *ExitPred : ExitPreds) {
+      // We only need to split loop exit edges.
+      Loop *PredLoop = LI->getLoopFor(ExitPred);
+      if (!PredLoop || PredLoop->contains(Exit) ||
+          isa<IndirectBrInst>(ExitPred->getTerminator()))
+        continue;
+      SplitLatchEdge |= L->getLoopLatch() == ExitPred;
+      BasicBlock *ExitSplit = SplitCriticalEdge(
+                                                ExitPred, Exit,
+                                                CriticalEdgeSplittingOptions(DT, LI, MSSAU).setPreserveLCSSA());
+      ExitSplit->moveBefore(Exit);
+    }
+    assert(SplitLatchEdge &&
+            "Despite splitting all preds, failed to split latch exit?");
+    (void)SplitLatchEdge;
+  } else {
+    // We can fold the conditional branch in the preheader, this makes things
+    // simpler. The first step is to remove the extra edge to the Exit block.
+    Exit->removePredecessor(OrigPreheader, true /*preserve LCSSA*/);
+    BranchInst *NewBI = BranchInst::Create(NewHeader, PHBI->getIterator());
+    NewBI->setDebugLoc(PHBI->getDebugLoc());
+    PHBI->eraseFromParent();
+
+    // With our CFG finalized, update DomTree if it is available.
+    if (DT) DT->deleteEdge(OrigPreheader, Exit);
+
+    // Update MSSA too, if available.
+    if (MSSAU)
+      MSSAU->removeEdge(OrigPreheader, Exit);
+  }
 
-    ++NumRotated;
+  assert(L->getLoopPreheader() && "Invalid loop preheader after loop rotation");
+  assert(L->getLoopLatch() && "Invalid loop latch after loop rotation");
 
-    Rotated = true;
-    SimplifiedLatch = false;
+  if (MSSAU && VerifyMemorySSA)
+    MSSAU->getMemorySSA()->verifyMemorySSA();
+
+  // Now that the CFG and DomTree are in a consistent state again, try to merge
+  // the OrigHeader block into OrigLatch.  This will succeed if they are
+  // connected by an unconditional branch.  This is just a cleanup so the
+  // emitted code isn't too gross in this common case.
+  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+  BasicBlock *PredBB = OrigHeader->getUniquePredecessor();
+  bool DidMerge = MergeBlockIntoPredecessor(OrigHeader, &DTU, LI, MSSAU);
+  if (DidMerge)
+    RemoveRedundantDbgInstrs(PredBB);
 
-    // Check that new latch is a deoptimizing exit and then repeat rotation if possible.
-    // Deoptimizing latch exit is not a generally typical case, so we just loop over.
-    // TODO: if it becomes a performance bottleneck extend rotation algorithm
-    // to handle multiple rotations in one go.
-  } while (MultiRotate && canRotateDeoptimizingLatchExit(L));
+  if (MSSAU && VerifyMemorySSA)
+    MSSAU->getMemorySSA()->verifyMemorySSA();
 
+  LLVM_DEBUG(dbgs() << "LoopRotation: into "; L->dump());
 
   return true;
 }
diff --git a/llvm/test/Transforms/LoopRotate/multiple-deopt-exits.ll b/llvm/test/Transforms/LoopRotate/multiple-deopt-exits.ll
deleted file mode 100644
index 72bc5434e2bed..0000000000000
--- a/llvm/test/Transforms/LoopRotate/multiple-deopt-exits.ll
+++ /dev/null
@@ -1,164 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S < %s -passes='loop(loop-rotate)' -loop-rotate-multi=true | FileCheck %s
-
-; Test loop rotation with multiple exits, some of them - deoptimizing.
-; We should end up with a latch which exit is non-deoptimizing, so we should rotate
-; more than once.
-
-declare i32 @llvm.experimental.deoptimize.i32(...)
-
-define i32 @test_cond_with_one_deopt_exit(ptr nonnull %a, i64 %x) {
-; Rotation done twice.
-; Latch should be at the 2nd condition (for.cond2), exiting to %return.
-;
-; CHECK-LABEL: @test_cond_with_one_deopt_exit(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[VAL_A_IDX3:%.*]] = load i32, ptr %a, align 4
-; CHECK-NEXT:    [[ZERO_CHECK4:%.*]] = icmp eq i32 [[VAL_A_IDX3]], 0
-; CHECK-NEXT:    br i1 [[ZERO_CHECK4]], label %deopt.exit, label %for.cond2.lr.ph
-; CHECK:       for.cond2.lr.ph:
-; CHECK-NEXT:    [[FOR_CHECK8:%.*]] = icmp ult i64 0, %x
-; CHECK-NEXT:    br i1 [[FOR_CHECK8]], label %for.body.lr.ph, label %return
-; CHECK:       for.body.lr.ph:
-; CHECK-NEXT:    br label %for.body
-; CHECK:       for.cond2:
-; CHECK:         [[FOR_CHECK:%.*]] = icmp ult i64 {{%.*}}, %x
-; CHECK-NEXT:    br i1 [[FOR_CHECK]], label %for.body, label %for.cond2.return_crit_edge
-; CHECK:       for.body:
-; CHECK:         br label %for.tail
-; CHECK:       for.tail:
-; CHECK:         [[VAL_A_IDX:%.*]] = load i32, ptr
-; CHECK-NEXT:    [[ZERO_CHECK:%.*]] = icmp eq i32 [[VAL_A_IDX]], 0
-; CHECK-NEXT:    br i1 [[ZERO_CHECK]], label %for.cond1.deopt.exit_crit_edge, label %for.cond2
-; CHECK:       for.cond2.return_crit_edge:
-; CHECK-NEXT:    {{%.*}} = phi i32
-; CHECK-NEXT:    br label %return
-; CHECK:       return:
-; CHECK-NEXT:    [[SUM_LCSSA2:%.*]] = phi i32
-; CHECK-NEXT:    ret i32 [[SUM_LCSSA2]]
-; CHECK:       for.cond1.deopt.exit_crit_edge:
-; CHECK-NEXT:    {{%.*}} = phi i32
-; CHECK-NEXT:    br label %deopt.exit
-; CHECK:       deopt.exit:
-; CHECK:         [[DEOPT_VAL:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 {{%.*}}) ]
-; CHECK-NEXT:    ret i32 [[DEOPT_VAL]]
-;
-entry:
-  br label %for.cond1
-
-for.cond1:
-  %idx = phi i64 [ 0, %entry ], [ %idx.next, %for.tail ]
-  %sum = phi i32 [ 0, %entry ], [ %sum.next, %for.tail ]
-  %a.idx = getelementptr inbounds i32, ptr %a, i64 %idx
-  %val.a.idx = load i32, ptr %a.idx, align 4
-  %zero.check = icmp eq i32 %val.a.idx, 0
-  br i1 %zero.check, label %deopt.exit, label %for.cond2
-
-for.cond2:
-  %for.check = icmp ult i64 %idx, %x
-  br i1 %for.check, label %for.body, label %return
-
-for.body:
-  br label %for.tail
-
-for.tail:
-  %sum.next = add i32 %sum, %val.a.idx
-  %idx.next = add nuw nsw i64 %idx, 1
-  br label %for.cond1
-
-return:
-  ret i32 %sum
-
-deopt.exit:
-  %deopt.val = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %val.a.idx) ]
-  ret i32 %deopt.val
-}
-
-define i32 @test_cond_with_two_deopt_exits(ptr nonnull %a, i64 %x) {
-; Rotation done three times.
-; Latch should be at the 3rd condition (for.cond3), exiting to %return.
-;
-; CHECK-LABEL: @test_cond_with_two_deopt_exits(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A_IDX_DEREF4:%.*]] = load ptr, ptr %a
-; CHECK-NEXT:    [[NULL_CHECK5:%.*]] = icmp eq ptr [[A_IDX_DEREF4]], null
-; CHECK-NEXT:    br i1 [[NULL_CHECK5]], label %deopt.exit1, label %for.cond2.lr.ph
-; CHECK:       for.cond2.lr.ph:
-; CHECK-NEXT:    [[VAL_A_IDX9:%.*]] = load i32, ptr [[A_IDX_DEREF4]], align 4
-; CHECK-NEXT:    [[ZERO_CHECK10:%.*]] = icmp eq i32 [[VAL_A_IDX9]], 0
-; CHECK-NEXT:    br i1 [[ZERO_CHECK10]], label %deopt.exit2, label %for.cond3.lr.ph
-; CHECK:       for.cond3.lr.ph:
-; CHECK-NEXT:    [[FOR_CHECK14:%.*]] = icmp ult i64 0, %x
-; CHECK-NEXT:    br i1 [[FOR_CHECK14]], label %for.body.lr.ph, label %return
-; CHECK:       for.body.lr.ph:
-; CHECK-NEXT:    br label %for.body
-; CHECK:       for.cond2:
-; CHECK:         [[VAL_A_IDX:%.*]] = load i32, ptr
-; CHECK-NEXT:    [[ZERO_CHECK:%.*]] = icmp eq i32 [[VAL_A_IDX]], 0
-; CHECK-NEXT:    br i1 [[ZERO_CHECK]], label %for.cond2.deopt.exit2_crit_edge, label %for.cond3
-; CHECK:       for.cond3:
-; CHECK:         [[FOR_CHECK:%.*]] = icmp ult i64 {{%.*}}, %x
-; CHECK-NEXT:    br i1 [[FOR_CHECK]], label %for.body, label %for.cond3.return_crit_edge
-; CHECK:       for.body:
-; CHECK:         br label %for.tail
-; CHECK:       for.tail:
-; CHECK:         [[IDX_NEXT:%.*]] = add nuw nsw i64 {{%.*}}, 1
-; CHECK:         [[NULL_CHECK:%.*]] = icmp eq ptr {{%.*}}, null
-; CHECK-NEXT:    br i1 [[NULL_CHECK]], label %for.cond1.deopt.exit1_crit_edge, label %for.cond2
-; CHECK:       for.cond3.return_crit_edge:
-; CHECK-NEXT:    [[SPLIT18:%.*]] = phi i32
-; CHECK-NEXT:    br label %return
-; CHECK:       return:
-; CHECK-NEXT:    [[SUM_LCSSA2:%.*]] = phi i32
-; CHECK-NEXT:    ret i32 [[SUM_LCSSA2]]
-; CHECK:       for.cond1.deopt.exit1_crit_edge:
-; CHECK-NEXT:    br label %deopt.exit1
-; CHECK:       deopt.exit1:
-; CHECK-NEXT:    [[DEOPT_VAL1:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 0) ]
-; CHECK-NEXT:    ret i32 [[DEOPT_VAL1]]
-; CHECK:       for.cond2.deopt.exit2_crit_edge:
-; CHECK-NEXT:    [[SPLIT:%.*]] = phi i32
-; CHECK-NEXT:    br label %deopt.exit2
-; CHECK:       deopt.exit2:
-; CHECK-NEXT:    [[VAL_A_IDX_LCSSA:%.*]] = phi i32
-; CHECK-NEXT:    [[DEOPT_VAL2:%.*]] = call i32 (...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 [[VAL_A_IDX_LCSSA]]) ]
-; CHECK-NEXT:    ret i32 [[DEOPT_VAL2]]
-;
-entry:
-  br label %for.cond1
-
-for.cond1:
-  %idx = phi i64 [ 0, %entry ], [ %idx.next, %for.tail ]
-  %sum = phi i32 [ 0, %entry ], [ %sum.next, %for.tail ]
-  %a.idx = getelementptr inbounds ptr, ptr %a, i64 %idx
-  %a.idx.deref = load ptr, ptr %a.idx
-  %null.check = icmp eq ptr %a.idx.deref, null
-  br i1 %null.check, label %deopt.exit1, label %for.cond2
-
-for.cond2:
-  %val.a.idx = load i32, ptr %a.idx.deref, align 4
-  %zero.check = icmp eq i32 %val.a.idx, 0
-  br i1 %zero.check, label %deopt.exit2, label %for.cond3
-
-for.cond3:
-  %for.check = icmp ult i64 %idx, %x
-  br i1 %for.check, label %for.body, label %return
-
-for.body:
-  br label %for.tail
-
-for.tail:
-  %sum.next = add i32 %sum, %val.a.idx
-  %idx.next = add nuw nsw i64 %idx, 1
-  br label %for.cond1
-
-return:
-  ret i32 %sum
-
-deopt.exit1:
-  %deopt.val1 = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 0) ]
-  ret i32 %deopt.val1
-deopt.exit2:
-  %deopt.val2 = call i32(...) @llvm.experimental.deoptimize.i32() [ "deopt"(i32 %val.a.idx) ]
-  ret i32 %deopt.val2
-}
diff --git a/llvm/test/Transforms/LoopRotate/multiple-exits.ll b/llvm/test/Transforms/LoopRotate/multiple-exits.ll
deleted file mode 100644
index 748700c2589ff..0000000000000
--- a/llvm/test/Transforms/LoopRotate/multiple-exits.ll
+++ /dev/null
@@ -1,236 +0,0 @@
-; RUN: opt -S -passes=loop-rotate < %s -verify-loop-info -verify-dom-info -verify-memoryssa | FileCheck %s
-
-target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
-target triple = "x86_64-apple-macosx10.8.0"
-
-; PR7447
-define i32 @test1(ptr nocapture %a) nounwind readonly {
-entry:
-  br label %for.cond
-
-for.cond:                                         ; preds = %for.cond1, %entry
-  %sum.0 = phi i32 [ 0, %entry ], [ %sum.1, %for.cond1 ]
-  %i.0 = phi i1 [ true, %entry ], [ false, %for.cond1 ]
-  br i1 %i.0, label %for.cond1, label %return
-
-for.cond1:                                        ; preds = %for.cond, %land.rhs
-  %sum.1 = phi i32 [ %add, %land.rhs ], [ %sum.0, %for.cond ]
-  %i.1 = phi i32 [ %inc, %land.rhs ], [ 0, %for.cond ]
-  %cmp2 = icmp ult i32 %i.1, 100
-  br i1 %cmp2, label %land.rhs, label %for.cond
-
-land.rhs:                                         ; preds = %for.cond1
-  %conv = zext i32 %i.1 to i64
-  %arrayidx = getelementptr inbounds [100 x i32], ptr %a, i64 0, i64 %conv
-  %0 = load i32, ptr %arrayidx, align 4
-  %add = add i32 %0, %sum.1
-  %cmp4 = icmp ugt i32 %add, 1000
-  %inc = add i32 %i.1, 1
-  br i1 %cmp4, label %return, label %for.cond1
-
-return:                                           ; preds = %for.cond, %land.rhs
-  %retval.0 = phi i32 [ 1000, %land.rhs ], [ %sum.0, %for.cond ]
-  ret i32 %retval.0
-
-; CHECK-LABEL: @test1(
-; CHECK: for.cond1.preheader:
-; CHECK: %sum.04 = phi i32 [ 0, %entry ], [ %sum.1.lcssa, %for.cond.loopexit ]
-; CHECK: br label %for.cond1
-
-; CHECK: for.cond1:
-; CHECK: %sum.1 = phi i32 [ %add, %land.rhs ], [ %sum.04, %for.cond1.preheader ]
-; CHECK: %i.1 = phi i32 [ %inc, %land.rhs ], [ 0, %for.cond1.preheader ]
-; CHECK: %cmp2 = icmp ult i32 %i.1, 100
-; CHECK: br i1 %cmp2, label %land.rhs, label %for.cond.loopexit
-}
-
-define void @test2(i32 %x) nounwind {
-entry:
-  br label %for.cond
-
-for.cond:                                         ; preds = %if.end, %entry
-  %i.0 = phi i32 [ 0, %entry ], [ %inc, %if.end ]
-  %cmp = icmp eq i32 %i.0, %x
-  br i1 %cmp, label %return.loopexit, label %for.body
-
-for.body:                                         ; preds = %for.cond
-  %call = tail call i32 @foo(i32 %i.0) nounwind
-  %tobool = icmp eq i32 %call, 0
-  br i1 %tobool, label %if.end, label %a
-
-if.end:                                           ; preds = %for.body
-  %call1 = tail call i32 @foo(i32 42) nounwind
-  %inc = add i32 %i.0, 1
-  br label %for.cond
-
-a:                                                ; preds = %for.body
-  %call2 = tail call i32 @bar(i32 1) nounwind
-  br label %return
-
-return.loopexit:                                  ; preds = %for.cond
-  br label %return
-
-return:                                           ; preds = %return.loopexit, %a
-  ret void
-
-; CHECK-LABEL: @test2(
-; CHECK: if.end:
-; CHECK: %inc = add i32 %i.02, 1
-; CHECK: %cmp = icmp eq i32 %inc, %x
-; CHECK: br i1 %cmp, label %for.cond.return.loopexit_crit_edge, label %for.body
-}
-
-declare i32 @foo(i32)
-
-declare i32 @bar(i32)
-
- at _ZTIi = external constant ptr
-
-; Verify dominators.
-define void @test3(i32 %x) personality ptr @__gxx_personality_v0 {
-entry:
-  %cmp2 = icmp eq i32 0, %x
-  br i1 %cmp2, label %try.cont.loopexit, label %for.body.lr.ph
-
-for.body.lr.ph:                                   ; preds = %entry
-  br label %for.body
-
-for.body:                                         ; preds = %for.body.lr.ph, %for.inc
-  %i.03 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.inc ]
-  invoke void @_Z3fooi(i32 %i.03)
-          to label %for.inc unwind label %lpad
-
-for.inc:                                          ; preds = %for.body
-  %inc = add i32 %i.03, 1
-  %cmp = icmp eq i32 %inc, %x
-  br i1 %cmp, label %for.cond.try.cont.loopexit_crit_edge, label %for.body
-
-lpad:                                             ; preds = %for.body
-  %0 = landingpad { ptr, i32 }
-          catch ptr @_ZTIi
-  %1 = extractvalue { ptr, i32 } %0, 0
-  %2 = extractvalue { ptr, i32 } %0, 1
-  %3 = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi) nounwind
-  %matches = icmp eq i32 %2, %3
-  br i1 %matches, label %catch, label %eh.resume
-
-catch:                                            ; preds = %lpad
-  %4 = tail call ptr @__cxa_begin_catch(ptr %1) nounwind
-  br i1 true, label %invoke.cont2.loopexit, label %for.body.i.lr.ph
-
-for.body.i.lr.ph:                                 ; preds = %catch
-  br label %for.body.i
-
-for.body.i:                                       ; preds = %for.body.i.lr.ph, %for.inc.i
-  %i.0.i1 = phi i32 [ 0, %for.body.i.lr.ph ], [ %inc.i, %for.inc.i ]
-  invoke void @_Z3fooi(i32 %i.0.i1)
-          to label %for.inc.i unwind label %lpad.i
-
-for.inc.i:                                        ; preds = %for.body.i
-  %inc.i = add i32 %i.0.i1, 1
-  %cmp.i = icmp eq i32 %inc.i, 0
-  br i1 %cmp.i, label %for.cond.i.invoke.cont2.loopexit_crit_edge, label %for.body.i
-
-lpad.i:                                           ; preds = %for.body.i
-  %5 = landingpad { ptr, i32 }
-          catch ptr @_ZTIi
-  %6 = extractvalue { ptr, i32 } %5, 0
-  %7 = extractvalue { ptr, i32 } %5, 1
-  %matches.i = icmp eq i32 %7, %3
-  br i1 %matches.i, label %catch.i, label %lpad1.body
-
-catch.i:                                          ; preds = %lpad.i
-  %8 = tail call ptr @__cxa_begin_catch(ptr %6) nounwind
-  invoke void @test3(i32 0)
-          to label %invoke.cont2.i unwind label %lpad1.i
-
-invoke.cont2.i:                                   ; preds = %catch.i
-  tail call void @__cxa_end_catch() nounwind
-  br label %invoke.cont2
-
-lpad1.i:                                          ; preds = %catch.i
-  %9 = landingpad { ptr, i32 }
-          cleanup
-  %10 = extractvalue { ptr, i32 } %9, 0
-  %11 = extractvalue { ptr, i32 } %9, 1
-  tail call void @__cxa_end_catch() nounwind
-  br label %lpad1.body
-
-for.cond.i.invoke.cont2.loopexit_crit_edge:       ; preds = %for.inc.i
-  br label %invoke.cont2.loopexit
-
-invoke.cont2.loopexit:                            ; preds = %for.cond.i.invoke.cont2.loopexit_crit_edge, %catch
-  br label %invoke.cont2
-
-invoke.cont2:                                     ; preds = %invoke.cont2.loopexit, %invoke.cont2.i
-  tail call void @__cxa_end_catch() nounwind
-  br label %try.cont
-
-for.cond.try.cont.loopexit_crit_edge:             ; preds = %for.inc
-  br label %try.cont.loopexit
-
-try.cont.loopexit:                                ; preds = %for.cond.try.cont.loopexit_crit_edge, %entry
-  br label %try.cont
-
-try.cont:                                         ; preds = %try.cont.loopexit, %invoke.cont2
-  ret void
-
-lpad1.body:                                       ; preds = %lpad1.i, %lpad.i
-  %exn.slot.0.i = phi ptr [ %10, %lpad1.i ], [ %6, %lpad.i ]
-  %ehselector.slot.0.i = phi i32 [ %11, %lpad1.i ], [ %7, %lpad.i ]
-  tail call void @__cxa_end_catch() nounwind
-  br label %eh.resume
-
-eh.resume:                                        ; preds = %lpad1.body, %lpad
-  %exn.slot.0 = phi ptr [ %exn.slot.0.i, %lpad1.body ], [ %1, %lpad ]
-  %ehselector.slot.0 = phi i32 [ %ehselector.slot.0.i, %lpad1.body ], [ %2, %lpad ]
-  %lpad.val = insertvalue { ptr, i32 } undef, ptr %exn.slot.0, 0
-  %lpad.val5 = insertvalue { ptr, i32 } %lpad.val, i32 %ehselector.slot.0, 1
-  resume { ptr, i32 } %lpad.val5
-}
-
-declare void @_Z3fooi(i32)
-
-declare i32 @__gxx_personality_v0(...)
-
-declare i32 @llvm.eh.typeid.for(ptr) nounwind readnone
-
-declare ptr @__cxa_begin_catch(ptr)
-
-declare void @__cxa_end_catch()
-
-define void @test4(i1 %arg) nounwind uwtable {
-entry:
-  br label %"7"
-
-"3":                                              ; preds = %"7"
-  br i1 %arg, label %"31", label %"4"
-
-"4":                                              ; preds = %"3"
-  %. = select i1 undef, float 0x3F50624DE0000000, float undef
-  %0 = add i32 %1, 1
-  br label %"7"
-
-"7":                                              ; preds = %"4", %entry
-  %1 = phi i32 [ %0, %"4" ], [ 0, %entry ]
-  %2 = icmp slt i32 %1, 100
-  br i1 %2, label %"3", label %"8"
-
-"8":                                              ; preds = %"7"
-  br i1 %arg, label %"9", label %"31"
-
-"9":                                              ; preds = %"8"
-  br label %"33"
-
-"27":                                             ; preds = %"31"
-  unreachable
-
-"31":                                             ; preds = %"8", %"3"
-  br i1 %arg, label %"27", label %"32"
-
-"32":                                             ; preds = %"31"
-  br label %"33"
-
-"33":                                             ; preds = %"32", %"9"
-  ret void
-}



More information about the llvm-commits mailing list