[llvm-branch-commits] [llvm] 5153817 - Revert "[FixIrreducible] Use CycleInfo instead of a custom SCC traversal (#10…"

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Aug 26 05:09:39 PDT 2024


Author: Alexey Bataev
Date: 2024-08-26T08:09:35-04:00
New Revision: 5153817e36dbaaf6800a5befb8c7a54363840e81

URL: https://github.com/llvm/llvm-project/commit/5153817e36dbaaf6800a5befb8c7a54363840e81
DIFF: https://github.com/llvm/llvm-project/commit/5153817e36dbaaf6800a5befb8c7a54363840e81.diff

LOG: Revert "[FixIrreducible] Use CycleInfo instead of a custom SCC traversal (#10…"

This reverts commit fa4cc9ddd58eb9fef2497e678873ff3b495340a3.

Added: 
    

Modified: 
    llvm/include/llvm/ADT/GenericCycleInfo.h
    llvm/lib/Transforms/Utils/FixIrreducible.cpp
    llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
    llvm/test/Transforms/FixIrreducible/basic.ll
    llvm/test/Transforms/FixIrreducible/bug45623.ll
    llvm/test/Transforms/FixIrreducible/nested.ll
    llvm/test/Transforms/FixIrreducible/switch.ll
    llvm/test/Transforms/FixIrreducible/unreachable.ll
    llvm/test/Transforms/StructurizeCFG/workarounds/needs-fix-reducible.ll
    llvm/test/Transforms/StructurizeCFG/workarounds/needs-fr-ule.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/GenericCycleInfo.h b/llvm/include/llvm/ADT/GenericCycleInfo.h
index 8c2fa0490e638a..55034844d30b0d 100644
--- a/llvm/include/llvm/ADT/GenericCycleInfo.h
+++ b/llvm/include/llvm/ADT/GenericCycleInfo.h
@@ -107,13 +107,6 @@ template <typename ContextT> class GenericCycle {
     return is_contained(Entries, Block);
   }
 
-  /// \brief Replace all entries with \p Block as single entry.
-  void setSingleEntry(BlockT *Block) {
-    assert(contains(Block));
-    Entries.clear();
-    Entries.push_back(Block);
-  }
-
   /// \brief Return whether \p Block is contained in the cycle.
   bool contains(const BlockT *Block) const { return Blocks.contains(Block); }
 
@@ -199,16 +192,11 @@ template <typename ContextT> class GenericCycle {
   //@{
   using const_entry_iterator =
       typename SmallVectorImpl<BlockT *>::const_iterator;
-  const_entry_iterator entry_begin() const { return Entries.begin(); }
-  const_entry_iterator entry_end() const { return Entries.end(); }
+
   size_t getNumEntries() const { return Entries.size(); }
   iterator_range<const_entry_iterator> entries() const {
-    return llvm::make_range(entry_begin(), entry_end());
+    return llvm::make_range(Entries.begin(), Entries.end());
   }
-  using const_reverse_entry_iterator =
-      typename SmallVectorImpl<BlockT *>::const_reverse_iterator;
-  const_reverse_entry_iterator entry_rbegin() const { return Entries.rbegin(); }
-  const_reverse_entry_iterator entry_rend() const { return Entries.rend(); }
   //@}
 
   Printable printEntries(const ContextT &Ctx) const {
@@ -267,6 +255,12 @@ template <typename ContextT> class GenericCycleInfo {
   /// the subtree.
   void moveTopLevelCycleToNewParent(CycleT *NewParent, CycleT *Child);
 
+  /// Assumes that \p Cycle is the innermost cycle containing \p Block.
+  /// \p Block will be appended to \p Cycle and all of its parent cycles.
+  /// \p Block will be added to BlockMap with \p Cycle and
+  /// BlockMapTopLevel with \p Cycle's top level parent cycle.
+  void addBlockToCycle(BlockT *Block, CycleT *Cycle);
+
 public:
   GenericCycleInfo() = default;
   GenericCycleInfo(GenericCycleInfo &&) = default;
@@ -284,12 +278,6 @@ template <typename ContextT> class GenericCycleInfo {
   unsigned getCycleDepth(const BlockT *Block) const;
   CycleT *getTopLevelParentCycle(BlockT *Block);
 
-  /// Assumes that \p Cycle is the innermost cycle containing \p Block.
-  /// \p Block will be appended to \p Cycle and all of its parent cycles.
-  /// \p Block will be added to BlockMap with \p Cycle and
-  /// BlockMapTopLevel with \p Cycle's top level parent cycle.
-  void addBlockToCycle(BlockT *Block, CycleT *Cycle);
-
   /// Methods for debug and self-test.
   //@{
   void verifyCycleNest(bool VerifyFull = false) const;

diff  --git a/llvm/lib/Transforms/Utils/FixIrreducible.cpp b/llvm/lib/Transforms/Utils/FixIrreducible.cpp
index 67fb806d3eae54..cdd4b36d2d9ebf 100644
--- a/llvm/lib/Transforms/Utils/FixIrreducible.cpp
+++ b/llvm/lib/Transforms/Utils/FixIrreducible.cpp
@@ -6,66 +6,50 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// INPUT CFG: The blocks H and B form an irreducible cycle with two headers.
+// An irreducible SCC is one which has multiple "header" blocks, i.e., blocks
+// with control-flow edges incident from outside the SCC.  This pass converts a
+// irreducible SCC into a natural loop by applying the following transformation:
+//
+// 1. Collect the set of headers H of the SCC.
+// 2. Collect the set of predecessors P of these headers. These may be inside as
+//    well as outside the SCC.
+// 3. Create block N and redirect every edge from set P to set H through N.
+//
+// This converts the SCC into a natural loop with N as the header: N is the only
+// block with edges incident from outside the SCC, and all backedges in the SCC
+// are incident on N, i.e., for every backedge, the head now dominates the tail.
+//
+// INPUT CFG: The blocks A and B form an irreducible loop with two headers.
 //
 //                        Entry
 //                       /     \
 //                      v       v
-//                      H ----> B
+//                      A ----> B
 //                      ^      /|
 //                       `----' |
 //                              v
 //                             Exit
 //
-// OUTPUT CFG: Converted to a natural loop with a new header N.
+// OUTPUT CFG: Edges incident on A and B are now redirected through a
+// new block N, forming a natural loop consisting of N, A and B.
 //
 //                        Entry
 //                          |
 //                          v
-//                          N <---.
-//                         / \     \
-//                        /   \     |
-//                       v     v    /
-//                       H --> B --'
+//                    .---> N <---.
+//                   /     / \     \
+//                  |     /   \     |
+//                  \    v     v    /
+//                   `-- A     B --'
 //                             |
 //                             v
 //                            Exit
 //
-// To convert an irreducible cycle C to a natural loop L:
-//
-// 1. Add a new node N to C.
-// 2. Redirect all external incoming edges through N.
-// 3. Redirect all edges incident on header H through N.
-//
-// This is sufficient to ensure that:
-//
-// a. Every closed path in C also exists in L, with the modification that any
-//    path passing through H now passes through N before reaching H.
-// b. Every external path incident on any entry of C is now incident on N and
-//    then redirected to the entry.
-//
-// Thus, L is a strongly connected component dominated by N, and hence L is a
-// natural loop with header N.
-//
-// When an irreducible cycle C with header H is transformed into a loop, the
-// following invariants hold:
-//
-// 1. No new subcycles are "discovered" in the set (C-H). The only internal
-//    edges that are redirected by the transform are incident on H. Any subcycle
-//    S in (C-H), already existed prior to this transform, and is already in the
-//    list of children for this cycle C.
-//
-// 2. Subcycles of C are not modified by the transform. For some subcycle S of
-//    C, edges incident on the entries of S are either internal to C, or they
-//    are now redirected through N, which is outside of S. So the list of
-//    entries to S does not change. Since the transform only adds a block
-//    outside S, and redirects edges that are not internal to S, the list of
-//    blocks in S does not change.
-//
-// 3. Similarly, any natural loop L included in C is not affected, with one
-//    exception: L is "destroyed" by the transform iff its header is H. The
-//    backedges of such a loop are now redirected to N instead, and hence the
-//    body of this loop gets merged into the new loop with header N.
+// The transformation is applied to every maximal SCC that is not already
+// recognized as a loop. The pass operates on all maximal SCCs found in the
+// function body outside of any loop, as well as those found inside each loop,
+// including inside any newly created loops. This ensures that any SCC hidden
+// inside a maximal SCC is also transformed.
 //
 // The actual transformation is handled by the ControlFlowHub, which redirects
 // specified control flow edges through a set of guard blocks. This also moves
@@ -83,9 +67,8 @@
 
 #include "llvm/Transforms/Utils/FixIrreducible.h"
 #include "llvm/ADT/SCCIterator.h"
-#include "llvm/Analysis/CycleAnalysis.h"
 #include "llvm/Analysis/DomTreeUpdater.h"
-#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/LoopIterator.h"
 #include "llvm/InitializePasses.h"
 #include "llvm/Pass.h"
 #include "llvm/Transforms/Utils.h"
@@ -105,9 +88,8 @@ struct FixIrreducible : public FunctionPass {
 
   void getAnalysisUsage(AnalysisUsage &AU) const override {
     AU.addRequired<DominatorTreeWrapperPass>();
-    AU.addRequired<CycleInfoWrapperPass>();
+    AU.addRequired<LoopInfoWrapperPass>();
     AU.addPreserved<DominatorTreeWrapperPass>();
-    AU.addPreserved<CycleInfoWrapperPass>();
     AU.addPreserved<LoopInfoWrapperPass>();
   }
 
@@ -131,14 +113,16 @@ INITIALIZE_PASS_END(FixIrreducible, "fix-irreducible",
 // When a new loop is created, existing children of the parent loop may now be
 // fully inside the new loop. Reconnect these as children of the new loop.
 static void reconnectChildLoops(LoopInfo &LI, Loop *ParentLoop, Loop *NewLoop,
-                                BasicBlock *OldHeader) {
+                                SetVector<BasicBlock *> &Blocks,
+                                SetVector<BasicBlock *> &Headers) {
   auto &CandidateLoops = ParentLoop ? ParentLoop->getSubLoopsVector()
                                     : LI.getTopLevelLoopsVector();
-  // Any candidate is a child iff its header is owned by the new loop. Move all
-  // the children to a new vector.
+  // The new loop cannot be its own child, and any candidate is a
+  // child iff its header is owned by the new loop. Move all the
+  // children to a new vector.
   auto FirstChild = std::partition(
       CandidateLoops.begin(), CandidateLoops.end(), [&](Loop *L) {
-        return NewLoop == L || !NewLoop->contains(L->getHeader());
+        return L == NewLoop || !Blocks.contains(L->getHeader());
       });
   SmallVector<Loop *, 8> ChildLoops(FirstChild, CandidateLoops.end());
   CandidateLoops.erase(FirstChild, CandidateLoops.end());
@@ -146,9 +130,10 @@ static void reconnectChildLoops(LoopInfo &LI, Loop *ParentLoop, Loop *NewLoop,
   for (Loop *Child : ChildLoops) {
     LLVM_DEBUG(dbgs() << "child loop: " << Child->getHeader()->getName()
                       << "\n");
-    // A child loop whose header was the old cycle header gets destroyed since
-    // its backedges are removed.
-    if (Child->getHeader() == OldHeader) {
+    // TODO: A child loop whose header is also a header in the current
+    // SCC gets destroyed since its backedges are removed. That may
+    // not be necessary if we can retain such backedges.
+    if (Headers.count(Child->getHeader())) {
       for (auto *BB : Child->blocks()) {
         if (LI.getLoopFor(BB) != Child)
           continue;
@@ -173,18 +158,63 @@ static void reconnectChildLoops(LoopInfo &LI, Loop *ParentLoop, Loop *NewLoop,
   }
 }
 
-static void updateLoopInfo(LoopInfo &LI, Cycle &C,
-                           ArrayRef<BasicBlock *> GuardBlocks) {
-  // The parent loop is a natural loop L mapped to the cycle header H as long as
-  // H is not also the header of L. In the latter case, L is destroyed and we
-  // seek its parent instead.
-  BasicBlock *CycleHeader = C.getHeader();
-  Loop *ParentLoop = LI.getLoopFor(CycleHeader);
-  if (ParentLoop && ParentLoop->getHeader() == CycleHeader)
-    ParentLoop = ParentLoop->getParentLoop();
+// Given a set of blocks and headers in an irreducible SCC, convert it into a
+// natural loop. Also insert this new loop at its appropriate place in the
+// hierarchy of loops.
+static void createNaturalLoopInternal(LoopInfo &LI, DominatorTree &DT,
+                                      Loop *ParentLoop,
+                                      SetVector<BasicBlock *> &Blocks,
+                                      SetVector<BasicBlock *> &Headers) {
+#ifndef NDEBUG
+  // All headers are part of the SCC
+  for (auto *H : Headers) {
+    assert(Blocks.count(H));
+  }
+#endif
+
+  SetVector<BasicBlock *> Predecessors;
+  for (auto *H : Headers) {
+    for (auto *P : predecessors(H)) {
+      Predecessors.insert(P);
+    }
+  }
+
+  LLVM_DEBUG(
+      dbgs() << "Found predecessors:";
+      for (auto P : Predecessors) {
+        dbgs() << " " << P->getName();
+      }
+      dbgs() << "\n");
+
+  // Redirect all the backedges through a "hub" consisting of a series
+  // of guard blocks that manage the flow of control from the
+  // predecessors to the headers.
+  ControlFlowHub CHub;
+  for (BasicBlock *P : Predecessors) {
+    auto *Branch = cast<BranchInst>(P->getTerminator());
+    BasicBlock *Succ0 = Branch->getSuccessor(0);
+    Succ0 = Headers.count(Succ0) ? Succ0 : nullptr;
+    BasicBlock *Succ1 =
+        Branch->isUnconditional() ? nullptr : Branch->getSuccessor(1);
+    Succ1 = Succ1 && Headers.count(Succ1) ? Succ1 : nullptr;
+    CHub.addBranch(P, Succ0, Succ1);
+
+    LLVM_DEBUG(dbgs() << "Added branch: " << P->getName() << " -> "
+                      << (Succ0 ? Succ0->getName() : "") << " "
+                      << (Succ1 ? Succ1->getName() : "") << "\n");
+  }
+
+  SmallVector<BasicBlock *, 8> GuardBlocks;
+  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
+  CHub.finalize(&DTU, GuardBlocks, "irr");
+#if defined(EXPENSIVE_CHECKS)
+  assert(DT.verify(DominatorTree::VerificationLevel::Full));
+#else
+  assert(DT.verify(DominatorTree::VerificationLevel::Fast));
+#endif
 
   // Create a new loop from the now-transformed cycle
-  auto *NewLoop = LI.AllocateLoop();
+  auto NewLoop = LI.AllocateLoop();
   if (ParentLoop) {
     ParentLoop->addChildLoop(NewLoop);
   } else {
@@ -197,11 +227,12 @@ static void updateLoopInfo(LoopInfo &LI, Cycle &C,
   // header. Since the new loop is already in LoopInfo, the new blocks
   // are also propagated up the chain of parent loops.
   for (auto *G : GuardBlocks) {
-    LLVM_DEBUG(dbgs() << "added guard block to loop: " << G->getName() << "\n");
+    LLVM_DEBUG(dbgs() << "added guard block: " << G->getName() << "\n");
     NewLoop->addBasicBlockToLoop(G, LI);
   }
 
-  for (auto *BB : C.blocks()) {
+  // Add the SCC blocks to the new loop.
+  for (auto *BB : Blocks) {
     NewLoop->addBlockEntry(BB);
     if (LI.getLoopFor(BB) == ParentLoop) {
       LLVM_DEBUG(dbgs() << "moved block from parent: " << BB->getName()
@@ -214,161 +245,129 @@ static void updateLoopInfo(LoopInfo &LI, Cycle &C,
   LLVM_DEBUG(dbgs() << "header for new loop: "
                     << NewLoop->getHeader()->getName() << "\n");
 
-  reconnectChildLoops(LI, ParentLoop, NewLoop, C.getHeader());
+  reconnectChildLoops(LI, ParentLoop, NewLoop, Blocks, Headers);
 
-  LLVM_DEBUG(dbgs() << "Verify new loop.\n"; NewLoop->print(dbgs()));
   NewLoop->verifyLoop();
   if (ParentLoop) {
-    LLVM_DEBUG(dbgs() << "Verify parent loop.\n"; ParentLoop->print(dbgs()));
     ParentLoop->verifyLoop();
   }
+#if defined(EXPENSIVE_CHECKS)
+  LI.verify(DT);
+#endif // EXPENSIVE_CHECKS
 }
 
-// Given a set of blocks and headers in an irreducible SCC, convert it into a
-// natural loop. Also insert this new loop at its appropriate place in the
-// hierarchy of loops.
-static bool fixIrreducible(Cycle &C, CycleInfo &CI, DominatorTree &DT,
-                           LoopInfo *LI) {
-  if (C.isReducible())
-    return false;
-  LLVM_DEBUG(dbgs() << "Processing cycle:\n" << CI.print(&C) << "\n";);
+namespace llvm {
+// Enable the graph traits required for traversing a Loop body.
+template <> struct GraphTraits<Loop> : LoopBodyTraits {};
+} // namespace llvm
 
-  ControlFlowHub CHub;
-  SetVector<BasicBlock *> Predecessors;
+// Overloaded wrappers to go with the function template below.
+static BasicBlock *unwrapBlock(BasicBlock *B) { return B; }
+static BasicBlock *unwrapBlock(LoopBodyTraits::NodeRef &N) { return N.second; }
 
-  // Redirect internal edges incident on the header.
-  BasicBlock *Header = C.getHeader();
-  for (BasicBlock *P : predecessors(Header)) {
-    if (C.contains(P))
-      Predecessors.insert(P);
-  }
-
-  for (BasicBlock *P : Predecessors) {
-    auto *Branch = cast<BranchInst>(P->getTerminator());
-    // Exactly one of the two successors is the header.
-    BasicBlock *Succ0 = Branch->getSuccessor(0) == Header ? Header : nullptr;
-    BasicBlock *Succ1 = Succ0 ? nullptr : Header;
-    if (!Succ0)
-      assert(Branch->getSuccessor(1) == Header);
-    assert(Succ0 || Succ1);
-    CHub.addBranch(P, Succ0, Succ1);
+static void createNaturalLoop(LoopInfo &LI, DominatorTree &DT, Function *F,
+                              SetVector<BasicBlock *> &Blocks,
+                              SetVector<BasicBlock *> &Headers) {
+  createNaturalLoopInternal(LI, DT, nullptr, Blocks, Headers);
+}
 
-    LLVM_DEBUG(dbgs() << "Added internal branch: " << P->getName() << " -> "
-                      << (Succ0 ? Succ0->getName() : "") << " "
-                      << (Succ1 ? Succ1->getName() : "") << "\n");
-  }
+static void createNaturalLoop(LoopInfo &LI, DominatorTree &DT, Loop &L,
+                              SetVector<BasicBlock *> &Blocks,
+                              SetVector<BasicBlock *> &Headers) {
+  createNaturalLoopInternal(LI, DT, &L, Blocks, Headers);
+}
 
-  // Redirect external incoming edges. This includes the edges on the header.
-  Predecessors.clear();
-  for (BasicBlock *E : C.entries()) {
-    for (BasicBlock *P : predecessors(E)) {
-      if (!C.contains(P))
-        Predecessors.insert(P);
+// Convert irreducible SCCs; Graph G may be a Function* or a Loop&.
+template <class Graph>
+static bool makeReducible(LoopInfo &LI, DominatorTree &DT, Graph &&G) {
+  bool Changed = false;
+  for (auto Scc = scc_begin(G); !Scc.isAtEnd(); ++Scc) {
+    if (Scc->size() < 2)
+      continue;
+    SetVector<BasicBlock *> Blocks;
+    LLVM_DEBUG(dbgs() << "Found SCC:");
+    for (auto N : *Scc) {
+      auto BB = unwrapBlock(N);
+      LLVM_DEBUG(dbgs() << " " << BB->getName());
+      Blocks.insert(BB);
     }
-  }
-
-  for (BasicBlock *P : Predecessors) {
-    auto *Branch = cast<BranchInst>(P->getTerminator());
-    BasicBlock *Succ0 = Branch->getSuccessor(0);
-    Succ0 = C.contains(Succ0) ? Succ0 : nullptr;
-    BasicBlock *Succ1 =
-        Branch->isUnconditional() ? nullptr : Branch->getSuccessor(1);
-    Succ1 = Succ1 && C.contains(Succ1) ? Succ1 : nullptr;
-    CHub.addBranch(P, Succ0, Succ1);
-
-    LLVM_DEBUG(dbgs() << "Added external branch: " << P->getName() << " -> "
-                      << (Succ0 ? Succ0->getName() : "") << " "
-                      << (Succ1 ? Succ1->getName() : "") << "\n");
-  }
-
-  // Redirect all the backedges through a "hub" consisting of a series
-  // of guard blocks that manage the flow of control from the
-  // predecessors to the headers.
-  SmallVector<BasicBlock *> GuardBlocks;
-
-  // Minor optimization: The cycle entries are discovered in an order that is
-  // the opposite of the order in which these blocks appear as branch targets.
-  // This results in a lot of condition inversions in the control flow out of
-  // the new ControlFlowHub, which can be mitigated if the orders match. So we
-  // reverse the entries when adding them to the hub.
-  SetVector<BasicBlock *> Entries;
-  Entries.insert(C.entry_rbegin(), C.entry_rend());
-
-  DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
-  CHub.finalize(&DTU, GuardBlocks, "irr");
-#if defined(EXPENSIVE_CHECKS)
-  assert(DT.verify(DominatorTree::VerificationLevel::Full));
-#else
-  assert(DT.verify(DominatorTree::VerificationLevel::Fast));
-#endif
-
-  // If we are updating LoopInfo, do that now before modifying the cycle. This
-  // ensures that the first guard block is the header of a new natural loop.
-  if (LI)
-    updateLoopInfo(*LI, C, GuardBlocks);
+    LLVM_DEBUG(dbgs() << "\n");
+
+    // Minor optimization: The SCC blocks are usually discovered in an order
+    // that is the opposite of the order in which these blocks appear as branch
+    // targets. This results in a lot of condition inversions in the control
+    // flow out of the new ControlFlowHub, which can be mitigated if the orders
+    // match. So we discover the headers using the reverse of the block order.
+    SetVector<BasicBlock *> Headers;
+    LLVM_DEBUG(dbgs() << "Found headers:");
+    for (auto *BB : reverse(Blocks)) {
+      for (const auto P : predecessors(BB)) {
+        // Skip unreachable predecessors.
+        if (!DT.isReachableFromEntry(P))
+          continue;
+        if (!Blocks.count(P)) {
+          LLVM_DEBUG(dbgs() << " " << BB->getName());
+          Headers.insert(BB);
+          break;
+        }
+      }
+    }
+    LLVM_DEBUG(dbgs() << "\n");
 
-  for (auto *G : GuardBlocks) {
-    LLVM_DEBUG(dbgs() << "added guard block to cycle: " << G->getName()
-                      << "\n");
-    CI.addBlockToCycle(G, &C);
+    if (Headers.size() == 1) {
+      assert(LI.isLoopHeader(Headers.front()));
+      LLVM_DEBUG(dbgs() << "Natural loop with a single header: skipped\n");
+      continue;
+    }
+    createNaturalLoop(LI, DT, G, Blocks, Headers);
+    Changed = true;
   }
-  C.setSingleEntry(GuardBlocks[0]);
-
-  C.verifyCycle();
-  if (Cycle *Parent = C.getParentCycle())
-    Parent->verifyCycle();
-
-  LLVM_DEBUG(dbgs() << "Finished one cycle:\n"; CI.print(dbgs()););
-  return true;
+  return Changed;
 }
 
-static bool FixIrreducibleImpl(Function &F, CycleInfo &CI, DominatorTree &DT,
-                               LoopInfo *LI) {
+static bool FixIrreducibleImpl(Function &F, LoopInfo &LI, DominatorTree &DT) {
   LLVM_DEBUG(dbgs() << "===== Fix irreducible control-flow in function: "
                     << F.getName() << "\n");
 
   assert(hasOnlySimpleTerminator(F) && "Unsupported block terminator.");
 
   bool Changed = false;
-  for (Cycle *TopCycle : CI.toplevel_cycles()) {
-    for (Cycle *C : depth_first(TopCycle)) {
-      Changed |= fixIrreducible(*C, CI, DT, LI);
-    }
+  SmallVector<Loop *, 8> WorkList;
+
+  LLVM_DEBUG(dbgs() << "visiting top-level\n");
+  Changed |= makeReducible(LI, DT, &F);
+
+  // Any SCCs reduced are now already in the list of top-level loops, so simply
+  // add them all to the worklist.
+  append_range(WorkList, LI);
+
+  while (!WorkList.empty()) {
+    auto L = WorkList.pop_back_val();
+    LLVM_DEBUG(dbgs() << "visiting loop with header "
+                      << L->getHeader()->getName() << "\n");
+    Changed |= makeReducible(LI, DT, *L);
+    // Any SCCs reduced are now already in the list of child loops, so simply
+    // add them all to the worklist.
+    WorkList.append(L->begin(), L->end());
   }
 
-  if (!Changed)
-    return false;
-
-#if defined(EXPENSIVE_CHECKS)
-  CI.verify();
-  if (LI) {
-    LI.verify(DT);
-  }
-#endif // EXPENSIVE_CHECKS
-
-  return true;
+  return Changed;
 }
 
 bool FixIrreducible::runOnFunction(Function &F) {
-  auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
-  LoopInfo *LI = LIWP ? &LIWP->getLoopInfo() : nullptr;
-  auto &CI = getAnalysis<CycleInfoWrapperPass>().getResult();
+  auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
   auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-  return FixIrreducibleImpl(F, CI, DT, LI);
+  return FixIrreducibleImpl(F, LI, DT);
 }
 
 PreservedAnalyses FixIrreduciblePass::run(Function &F,
                                           FunctionAnalysisManager &AM) {
-  auto *LI = AM.getCachedResult<LoopAnalysis>(F);
-  auto &CI = AM.getResult<CycleAnalysis>(F);
+  auto &LI = AM.getResult<LoopAnalysis>(F);
   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
-
-  if (!FixIrreducibleImpl(F, CI, DT, LI))
+  if (!FixIrreducibleImpl(F, LI, DT))
     return PreservedAnalyses::all();
-
   PreservedAnalyses PA;
   PA.preserve<LoopAnalysis>();
-  PA.preserve<CycleAnalysis>();
   PA.preserve<DominatorTreeAnalysis>();
   return PA;
 }

diff  --git a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
index 29e8ebdafb5871..57575f786152bd 100644
--- a/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
+++ b/llvm/test/CodeGen/AMDGPU/llc-pipeline.ll
@@ -67,9 +67,8 @@
 ; GCN-O0-NEXT:        Uniformity Analysis
 ; GCN-O0-NEXT:        Unify divergent function exit nodes
 ; GCN-O0-NEXT:        Dominator Tree Construction
-; GCN-O0-NEXT:        Cycle Info Analysis
-; GCN-O0-NEXT:        Convert irreducible control-flow into natural loops
 ; GCN-O0-NEXT:        Natural Loop Information
+; GCN-O0-NEXT:        Convert irreducible control-flow into natural loops
 ; GCN-O0-NEXT:        Fixup each natural loop to have a single exit block
 ; GCN-O0-NEXT:        Post-Dominator Tree Construction
 ; GCN-O0-NEXT:        Dominance Frontier Construction
@@ -261,9 +260,8 @@
 ; GCN-O1-NEXT:        Post-Dominator Tree Construction
 ; GCN-O1-NEXT:        Unify divergent function exit nodes
 ; GCN-O1-NEXT:        Dominator Tree Construction
-; GCN-O1-NEXT:        Cycle Info Analysis
-; GCN-O1-NEXT:        Convert irreducible control-flow into natural loops
 ; GCN-O1-NEXT:        Natural Loop Information
+; GCN-O1-NEXT:        Convert irreducible control-flow into natural loops
 ; GCN-O1-NEXT:        Fixup each natural loop to have a single exit block
 ; GCN-O1-NEXT:        Post-Dominator Tree Construction
 ; GCN-O1-NEXT:        Dominance Frontier Construction
@@ -558,9 +556,8 @@
 ; GCN-O1-OPTS-NEXT:        Post-Dominator Tree Construction
 ; GCN-O1-OPTS-NEXT:        Unify divergent function exit nodes
 ; GCN-O1-OPTS-NEXT:        Dominator Tree Construction
-; GCN-O1-OPTS-NEXT:        Cycle Info Analysis
-; GCN-O1-OPTS-NEXT:        Convert irreducible control-flow into natural loops
 ; GCN-O1-OPTS-NEXT:        Natural Loop Information
+; GCN-O1-OPTS-NEXT:        Convert irreducible control-flow into natural loops
 ; GCN-O1-OPTS-NEXT:        Fixup each natural loop to have a single exit block
 ; GCN-O1-OPTS-NEXT:        Post-Dominator Tree Construction
 ; GCN-O1-OPTS-NEXT:        Dominance Frontier Construction
@@ -867,9 +864,8 @@
 ; GCN-O2-NEXT:        Post-Dominator Tree Construction
 ; GCN-O2-NEXT:        Unify divergent function exit nodes
 ; GCN-O2-NEXT:        Dominator Tree Construction
-; GCN-O2-NEXT:        Cycle Info Analysis
-; GCN-O2-NEXT:        Convert irreducible control-flow into natural loops
 ; GCN-O2-NEXT:        Natural Loop Information
+; GCN-O2-NEXT:        Convert irreducible control-flow into natural loops
 ; GCN-O2-NEXT:        Fixup each natural loop to have a single exit block
 ; GCN-O2-NEXT:        Post-Dominator Tree Construction
 ; GCN-O2-NEXT:        Dominance Frontier Construction
@@ -1190,9 +1186,8 @@
 ; GCN-O3-NEXT:        Post-Dominator Tree Construction
 ; GCN-O3-NEXT:        Unify divergent function exit nodes
 ; GCN-O3-NEXT:        Dominator Tree Construction
-; GCN-O3-NEXT:        Cycle Info Analysis
-; GCN-O3-NEXT:        Convert irreducible control-flow into natural loops
 ; GCN-O3-NEXT:        Natural Loop Information
+; GCN-O3-NEXT:        Convert irreducible control-flow into natural loops
 ; GCN-O3-NEXT:        Fixup each natural loop to have a single exit block
 ; GCN-O3-NEXT:        Post-Dominator Tree Construction
 ; GCN-O3-NEXT:        Dominance Frontier Construction

diff  --git a/llvm/test/Transforms/FixIrreducible/basic.ll b/llvm/test/Transforms/FixIrreducible/basic.ll
index 7f81e89bc5f5b4..30591c80c5559d 100644
--- a/llvm/test/Transforms/FixIrreducible/basic.ll
+++ b/llvm/test/Transforms/FixIrreducible/basic.ll
@@ -1,27 +1,24 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -fix-irreducible --verify-loop-info -S | FileCheck %s
-; RUN: opt < %s -passes='fix-irreducible,verify<loops>' -S | FileCheck %s
-; RUN: opt < %s -passes='verify<loops>,fix-irreducible,verify<loops>' -S | FileCheck %s
+; RUN: opt < %s -passes='fix-irreducible,verify<loops>' -S | FileCheck %s -check-prefix=CHECK
 
 define i32 @basic(i1 %PredEntry, i1 %PredLeft, i1 %PredRight, i32 %X, i32 %Y) {
 ; CHECK-LABEL: @basic(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PREDENTRY_INV:%.*]] = xor i1 [[PREDENTRY:%.*]], true
 ; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
 ; CHECK:       left:
-; CHECK-NEXT:    [[L_PHI:%.*]] = phi i32 [ [[R_PHI_MOVED:%.*]], [[RIGHT:%.*]] ], [ [[L_PHI_MOVED:%.*]], [[IRR_GUARD]] ]
-; CHECK-NEXT:    [[L:%.*]] = add i32 [[L_PHI]], 1
+; CHECK-NEXT:    [[L:%.*]] = add i32 [[L_PHI_MOVED:%.*]], 1
 ; CHECK-NEXT:    br i1 [[PREDLEFT:%.*]], label [[IRR_GUARD]], label [[EXIT:%.*]]
 ; CHECK:       right:
-; CHECK-NEXT:    br i1 [[PREDRIGHT:%.*]], label [[LEFT:%.*]], label [[EXIT]]
+; CHECK-NEXT:    br i1 [[PREDRIGHT:%.*]], label [[IRR_GUARD]], label [[EXIT]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[Z:%.*]] = phi i32 [ [[L]], [[LEFT]] ], [ [[R_PHI_MOVED]], [[RIGHT]] ]
+; CHECK-NEXT:    [[Z:%.*]] = phi i32 [ [[L]], [[LEFT:%.*]] ], [ [[R_PHI_MOVED:%.*]], [[RIGHT:%.*]] ]
 ; CHECK-NEXT:    ret i32 [[Z]]
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[L_PHI_MOVED]] = phi i32 [ [[L_PHI_MOVED]], [[LEFT]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[R_PHI_MOVED]] = phi i32 [ [[L]], [[LEFT]] ], [ [[Y:%.*]], [[ENTRY]] ]
-; CHECK-NEXT:    [[GUARD_RIGHT:%.*]] = phi i1 [ true, [[LEFT]] ], [ [[PREDENTRY_INV]], [[ENTRY]] ]
-; CHECK-NEXT:    br i1 [[GUARD_RIGHT]], label [[RIGHT]], label [[LEFT]]
+; CHECK-NEXT:    [[R_PHI_MOVED]] = phi i32 [ [[R_PHI_MOVED]], [[RIGHT]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ], [ [[L]], [[LEFT]] ]
+; CHECK-NEXT:    [[L_PHI_MOVED]] = phi i32 [ [[R_PHI_MOVED]], [[RIGHT]] ], [ [[X:%.*]], [[ENTRY]] ], [ [[L_PHI_MOVED]], [[LEFT]] ]
+; CHECK-NEXT:    [[GUARD_LEFT:%.*]] = phi i1 [ true, [[RIGHT]] ], [ [[PREDENTRY:%.*]], [[ENTRY]] ], [ false, [[LEFT]] ]
+; CHECK-NEXT:    br i1 [[GUARD_LEFT]], label [[LEFT]], label [[RIGHT]]
 ;
 entry:
   br i1 %PredEntry, label %left, label %right
@@ -43,21 +40,19 @@ exit:
 define i32 @feedback_loop(i1 %PredEntry, i1 %PredLeft, i1 %PredRight, i32 %X, i32 %Y) {
 ; CHECK-LABEL: @feedback_loop(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PREDENTRY_INV:%.*]] = xor i1 [[PREDENTRY:%.*]], true
 ; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
 ; CHECK:       left:
-; CHECK-NEXT:    [[L_PHI:%.*]] = phi i32 [ [[R_PHI_MOVED:%.*]], [[RIGHT:%.*]] ], [ [[L_PHI_MOVED:%.*]], [[IRR_GUARD]] ]
 ; CHECK-NEXT:    br i1 [[PREDLEFT:%.*]], label [[IRR_GUARD]], label [[EXIT:%.*]]
 ; CHECK:       right:
-; CHECK-NEXT:    br i1 [[PREDRIGHT:%.*]], label [[LEFT:%.*]], label [[EXIT]]
+; CHECK-NEXT:    br i1 [[PREDRIGHT:%.*]], label [[IRR_GUARD]], label [[EXIT]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[Z:%.*]] = phi i32 [ [[L_PHI]], [[LEFT]] ], [ [[R_PHI_MOVED]], [[RIGHT]] ]
+; CHECK-NEXT:    [[Z:%.*]] = phi i32 [ [[L_PHI_MOVED:%.*]], [[LEFT:%.*]] ], [ [[R_PHI_MOVED:%.*]], [[RIGHT:%.*]] ]
 ; CHECK-NEXT:    ret i32 [[Z]]
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[L_PHI_MOVED]] = phi i32 [ [[L_PHI_MOVED]], [[LEFT]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[R_PHI_MOVED]] = phi i32 [ [[L_PHI]], [[LEFT]] ], [ [[Y:%.*]], [[ENTRY]] ]
-; CHECK-NEXT:    [[GUARD_RIGHT:%.*]] = phi i1 [ true, [[LEFT]] ], [ [[PREDENTRY_INV]], [[ENTRY]] ]
-; CHECK-NEXT:    br i1 [[GUARD_RIGHT]], label [[RIGHT]], label [[LEFT]]
+; CHECK-NEXT:    [[R_PHI_MOVED]] = phi i32 [ [[R_PHI_MOVED]], [[RIGHT]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ], [ [[L_PHI_MOVED]], [[LEFT]] ]
+; CHECK-NEXT:    [[L_PHI_MOVED]] = phi i32 [ [[R_PHI_MOVED]], [[RIGHT]] ], [ [[X:%.*]], [[ENTRY]] ], [ [[L_PHI_MOVED]], [[LEFT]] ]
+; CHECK-NEXT:    [[GUARD_LEFT:%.*]] = phi i1 [ true, [[RIGHT]] ], [ [[PREDENTRY:%.*]], [[ENTRY]] ], [ false, [[LEFT]] ]
+; CHECK-NEXT:    br i1 [[GUARD_LEFT]], label [[LEFT]], label [[RIGHT]]
 ;
 entry:
   br i1 %PredEntry, label %left, label %right
@@ -86,18 +81,17 @@ define i32 @multiple_predecessors(i1 %PredEntry, i1 %PredA, i1 %PredB, i1 %PredC
 ; CHECK:       B:
 ; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       C:
-; CHECK-NEXT:    br i1 [[PREDC:%.*]], label [[D:%.*]], label [[EXIT:%.*]]
+; CHECK-NEXT:    br i1 [[PREDC:%.*]], label [[IRR_GUARD]], label [[EXIT:%.*]]
 ; CHECK:       D:
-; CHECK-NEXT:    [[D_PHI:%.*]] = phi i32 [ [[C_PHI_MOVED:%.*]], [[C:%.*]] ], [ [[D_PHI_MOVED:%.*]], [[IRR_GUARD]] ]
-; CHECK-NEXT:    [[D_INC:%.*]] = add i32 [[D_PHI]], 1
+; CHECK-NEXT:    [[D_INC:%.*]] = add i32 [[D_PHI_MOVED:%.*]], 1
 ; CHECK-NEXT:    br i1 [[PREDD:%.*]], label [[EXIT]], label [[IRR_GUARD]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[C_PHI_MOVED]], [[C]] ], [ [[D_INC]], [[D]] ]
+; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[C_PHI_MOVED:%.*]], [[C:%.*]] ], [ [[D_INC]], [[D:%.*]] ]
 ; CHECK-NEXT:    ret i32 [[RET]]
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[D_PHI_MOVED]] = phi i32 [ [[D_PHI_MOVED]], [[D]] ], [ [[Y:%.*]], [[B]] ], [ [[A_INC]], [[A]] ]
-; CHECK-NEXT:    [[C_PHI_MOVED]] = phi i32 [ [[D_INC]], [[D]] ], [ [[Y]], [[B]] ], [ [[X]], [[A]] ]
-; CHECK-NEXT:    [[GUARD_C:%.*]] = phi i1 [ true, [[D]] ], [ [[PREDB_INV]], [[B]] ], [ [[PREDA:%.*]], [[A]] ]
+; CHECK-NEXT:    [[D_PHI_MOVED]] = phi i32 [ [[D_PHI_MOVED]], [[D]] ], [ [[Y:%.*]], [[B]] ], [ [[A_INC]], [[A]] ], [ [[C_PHI_MOVED]], [[C]] ]
+; CHECK-NEXT:    [[C_PHI_MOVED]] = phi i32 [ [[D_INC]], [[D]] ], [ [[Y]], [[B]] ], [ [[X]], [[A]] ], [ [[C_PHI_MOVED]], [[C]] ]
+; CHECK-NEXT:    [[GUARD_C:%.*]] = phi i1 [ true, [[D]] ], [ [[PREDB_INV]], [[B]] ], [ [[PREDA:%.*]], [[A]] ], [ false, [[C]] ]
 ; CHECK-NEXT:    br i1 [[GUARD_C]], label [[C]], label [[D]]
 ;
 entry:
@@ -134,19 +128,18 @@ define i32 @separate_predecessors(i1 %PredEntry, i1 %PredA, i1 %PredB, i1 %PredC
 ; CHECK:       B:
 ; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       C:
-; CHECK-NEXT:    [[C_PHI:%.*]] = phi i32 [ [[D_INC:%.*]], [[D:%.*]] ], [ [[C_PHI_MOVED:%.*]], [[IRR_GUARD]] ]
 ; CHECK-NEXT:    br i1 [[PREDC:%.*]], label [[EXIT:%.*]], label [[IRR_GUARD]]
 ; CHECK:       D:
-; CHECK-NEXT:    [[D_INC]] = add i32 [[D_PHI_MOVED:%.*]], 1
-; CHECK-NEXT:    br i1 [[PREDD:%.*]], label [[EXIT]], label [[C:%.*]]
+; CHECK-NEXT:    [[D_INC:%.*]] = add i32 [[D_PHI_MOVED:%.*]], 1
+; CHECK-NEXT:    br i1 [[PREDD:%.*]], label [[EXIT]], label [[IRR_GUARD]]
 ; CHECK:       exit:
-; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[C_PHI]], [[C]] ], [ [[D_INC]], [[D]] ]
+; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[C_PHI_MOVED:%.*]], [[C:%.*]] ], [ [[D_INC]], [[D:%.*]] ]
 ; CHECK-NEXT:    ret i32 [[RET]]
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[C_PHI_MOVED]] = phi i32 [ [[C_PHI_MOVED]], [[C]] ], [ poison, [[B]] ], [ [[X]], [[A]] ]
-; CHECK-NEXT:    [[D_PHI_MOVED]] = phi i32 [ [[C_PHI]], [[C]] ], [ [[Y:%.*]], [[B]] ], [ poison, [[A]] ]
-; CHECK-NEXT:    [[GUARD_D:%.*]] = phi i1 [ true, [[C]] ], [ true, [[B]] ], [ false, [[A]] ]
-; CHECK-NEXT:    br i1 [[GUARD_D]], label [[D]], label [[C]]
+; CHECK-NEXT:    [[D_PHI_MOVED]] = phi i32 [ [[D_PHI_MOVED]], [[D]] ], [ poison, [[A]] ], [ [[C_PHI_MOVED]], [[C]] ], [ [[Y:%.*]], [[B]] ]
+; CHECK-NEXT:    [[C_PHI_MOVED]] = phi i32 [ [[D_INC]], [[D]] ], [ [[X]], [[A]] ], [ [[C_PHI_MOVED]], [[C]] ], [ poison, [[B]] ]
+; CHECK-NEXT:    [[GUARD_C:%.*]] = phi i1 [ true, [[D]] ], [ true, [[A]] ], [ false, [[C]] ], [ false, [[B]] ]
+; CHECK-NEXT:    br i1 [[GUARD_C]], label [[C]], label [[D]]
 ;
 entry:
   br i1 %PredEntry, label %A, label %B
@@ -175,31 +168,30 @@ exit:
 define void @four_headers(i1 %PredEntry, i1 %PredX, i1  %PredY, i1 %PredD) {
 ; CHECK-LABEL: @four_headers(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PREDY_INV:%.*]] = xor i1 [[PREDY:%.*]], true
 ; CHECK-NEXT:    br i1 [[PREDENTRY:%.*]], label [[X:%.*]], label [[Y:%.*]]
 ; CHECK:       X:
 ; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
 ; CHECK:       Y:
 ; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       A:
-; CHECK-NEXT:    br label [[B:%.*]]
+; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       B:
-; CHECK-NEXT:    br label [[C:%.*]]
+; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       C:
 ; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       D:
-; CHECK-NEXT:    br i1 [[PREDD:%.*]], label [[EXIT:%.*]], label [[A:%.*]]
+; CHECK-NEXT:    br i1 [[PREDD:%.*]], label [[EXIT:%.*]], label [[IRR_GUARD]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_D:%.*]] = phi i1 [ true, [[C]] ], [ [[PREDY_INV]], [[Y]] ], [ false, [[X]] ]
-; CHECK-NEXT:    [[GUARD_C:%.*]] = phi i1 [ false, [[C]] ], [ true, [[Y]] ], [ false, [[X]] ]
-; CHECK-NEXT:    [[GUARD_A:%.*]] = phi i1 [ false, [[C]] ], [ false, [[Y]] ], [ [[PREDX:%.*]], [[X]] ]
-; CHECK-NEXT:    br i1 [[GUARD_D]], label [[D:%.*]], label [[IRR_GUARD1:%.*]]
+; CHECK-NEXT:    [[GUARD_A:%.*]] = phi i1 [ true, [[D:%.*]] ], [ [[PREDX:%.*]], [[X]] ], [ false, [[A:%.*]] ], [ false, [[B:%.*]] ], [ false, [[Y]] ], [ false, [[C:%.*]] ]
+; CHECK-NEXT:    [[GUARD_B:%.*]] = phi i1 [ false, [[D]] ], [ true, [[X]] ], [ true, [[A]] ], [ false, [[B]] ], [ false, [[Y]] ], [ false, [[C]] ]
+; CHECK-NEXT:    [[GUARD_C:%.*]] = phi i1 [ false, [[D]] ], [ false, [[X]] ], [ false, [[A]] ], [ true, [[B]] ], [ [[PREDY:%.*]], [[Y]] ], [ false, [[C]] ]
+; CHECK-NEXT:    br i1 [[GUARD_A]], label [[A]], label [[IRR_GUARD1:%.*]]
 ; CHECK:       irr.guard1:
-; CHECK-NEXT:    br i1 [[GUARD_C]], label [[C]], label [[IRR_GUARD2:%.*]]
+; CHECK-NEXT:    br i1 [[GUARD_B]], label [[B]], label [[IRR_GUARD2:%.*]]
 ; CHECK:       irr.guard2:
-; CHECK-NEXT:    br i1 [[GUARD_A]], label [[A]], label [[B]]
+; CHECK-NEXT:    br i1 [[GUARD_C]], label [[C]], label [[D]]
 ;
 entry:
   br i1 %PredEntry, label %X, label %Y
@@ -229,28 +221,26 @@ exit:
 define i32 @hidden_nodes(i1 %PredEntry, i1 %PredA, i1 %PredB, i1 %PredC, i1 %PredD, i32 %X, i32 %Y) {
 ; CHECK-LABEL: @hidden_nodes(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PREDENTRY_INV:%.*]] = xor i1 [[PREDENTRY:%.*]], true
 ; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
 ; CHECK:       A:
-; CHECK-NEXT:    [[A_PHI:%.*]] = phi i32 [ [[C_INC:%.*]], [[E:%.*]] ], [ [[A_PHI_MOVED:%.*]], [[IRR_GUARD]] ]
-; CHECK-NEXT:    [[A_INC:%.*]] = add i32 [[A_PHI]], 1
+; CHECK-NEXT:    [[A_INC:%.*]] = add i32 [[A_PHI_MOVED:%.*]], 1
 ; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       B:
 ; CHECK-NEXT:    br label [[C:%.*]]
 ; CHECK:       C:
-; CHECK-NEXT:    [[C_INC]] = add i32 [[B_PHI_MOVED:%.*]], 1
+; CHECK-NEXT:    [[C_INC:%.*]] = add i32 [[B_PHI_MOVED:%.*]], 1
 ; CHECK-NEXT:    br label [[D:%.*]]
 ; CHECK:       D:
-; CHECK-NEXT:    br i1 [[PREDD:%.*]], label [[EXIT:%.*]], label [[E]]
+; CHECK-NEXT:    br i1 [[PREDD:%.*]], label [[EXIT:%.*]], label [[E:%.*]]
 ; CHECK:       E:
-; CHECK-NEXT:    br label [[A:%.*]]
+; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret i32 [[B_PHI_MOVED]]
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[A_PHI_MOVED]] = phi i32 [ [[A_PHI_MOVED]], [[A]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[B_PHI_MOVED]] = phi i32 [ [[A_INC]], [[A]] ], [ [[Y:%.*]], [[ENTRY]] ]
-; CHECK-NEXT:    [[GUARD_B:%.*]] = phi i1 [ true, [[A]] ], [ [[PREDENTRY_INV]], [[ENTRY]] ]
-; CHECK-NEXT:    br i1 [[GUARD_B]], label [[B:%.*]], label [[A]]
+; CHECK-NEXT:    [[B_PHI_MOVED]] = phi i32 [ poison, [[E]] ], [ [[Y:%.*]], [[ENTRY:%.*]] ], [ [[A_INC]], [[A:%.*]] ]
+; CHECK-NEXT:    [[A_PHI_MOVED]] = phi i32 [ [[C_INC]], [[E]] ], [ [[X:%.*]], [[ENTRY]] ], [ [[A_PHI_MOVED]], [[A]] ]
+; CHECK-NEXT:    [[GUARD_A:%.*]] = phi i1 [ true, [[E]] ], [ [[PREDENTRY:%.*]], [[ENTRY]] ], [ false, [[A]] ]
+; CHECK-NEXT:    br i1 [[GUARD_A]], label [[A]], label [[B:%.*]]
 ;
 entry:
   br i1 %PredEntry, label %A, label %B

diff  --git a/llvm/test/Transforms/FixIrreducible/bug45623.ll b/llvm/test/Transforms/FixIrreducible/bug45623.ll
index beddc967ebb0b6..c78b593e9319b1 100644
--- a/llvm/test/Transforms/FixIrreducible/bug45623.ll
+++ b/llvm/test/Transforms/FixIrreducible/bug45623.ll
@@ -1,7 +1,6 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -fix-irreducible --verify-loop-info -S | FileCheck %s
 ; RUN: opt < %s -passes='fix-irreducible,verify<loops>' -S | FileCheck %s
-; RUN: opt < %s -passes='verify<loops>,fix-irreducible,verify<loops>' -S | FileCheck %s
 
 define dso_local void @tre_tnfa_run_backtrack() {
 ; CHECK-LABEL: @tre_tnfa_run_backtrack(
@@ -14,7 +13,7 @@ define dso_local void @tre_tnfa_run_backtrack() {
 ; CHECK:       if.then250:
 ; CHECK-NEXT:    br label [[FOR_COND264:%.*]]
 ; CHECK:       for.cond264:
-; CHECK-NEXT:    br i1 undef, label [[FOR_BODY267:%.*]], label [[BACKTRACK:%.*]]
+; CHECK-NEXT:    br i1 undef, label [[FOR_BODY267:%.*]], label [[IRR_GUARD]]
 ; CHECK:       for.body267:
 ; CHECK-NEXT:    br label [[FOR_COND264]]
 ; CHECK:       if.end275:
@@ -24,7 +23,7 @@ define dso_local void @tre_tnfa_run_backtrack() {
 ; CHECK:       for.body345:
 ; CHECK-NEXT:    br label [[FOR_COND342]]
 ; CHECK:       for.end580:
-; CHECK-NEXT:    br label [[BACKTRACK]]
+; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       backtrack:
 ; CHECK-NEXT:    br i1 undef, label [[IF_THEN595:%.*]], label [[IF_ELSE629:%.*]]
 ; CHECK:       if.then595:
@@ -38,8 +37,8 @@ define dso_local void @tre_tnfa_run_backtrack() {
 ; CHECK:       if.else629:
 ; CHECK-NEXT:    br label [[RETRY]]
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_WHILE_BODY248:%.*]] = phi i1 [ true, [[FOR_END626]] ], [ undef, [[RETRY]] ]
-; CHECK-NEXT:    br i1 [[GUARD_WHILE_BODY248]], label [[WHILE_BODY248:%.*]], label [[BACKTRACK]]
+; CHECK-NEXT:    [[GUARD_BACKTRACK:%.*]] = phi i1 [ true, [[FOR_END580]] ], [ true, [[FOR_COND264]] ], [ undef, [[RETRY]] ], [ false, [[FOR_END626]] ]
+; CHECK-NEXT:    br i1 [[GUARD_BACKTRACK]], label [[BACKTRACK:%.*]], label [[WHILE_BODY248:%.*]]
 ;
 entry:
   br label %retry

diff  --git a/llvm/test/Transforms/FixIrreducible/nested.ll b/llvm/test/Transforms/FixIrreducible/nested.ll
index 0cc6b473d62f69..1665bbf9930287 100644
--- a/llvm/test/Transforms/FixIrreducible/nested.ll
+++ b/llvm/test/Transforms/FixIrreducible/nested.ll
@@ -1,32 +1,29 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -fix-irreducible --verify-loop-info -S | FileCheck %s
 ; RUN: opt < %s -passes='fix-irreducible,verify<loops>' -S | FileCheck %s
-; RUN: opt < %s -passes='verify<loops>,fix-irreducible,verify<loops>' -S | FileCheck %s
 
 define void @nested_irr_top_level(i1 %Pred0, i1 %Pred1, i1 %Pred2, i1 %Pred3, i1 %Pred4, i1 %Pred5) {
 ; CHECK-LABEL: @nested_irr_top_level(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PRED1_INV:%.*]] = xor i1 [[PRED1:%.*]], true
-; CHECK-NEXT:    [[PRED0_INV:%.*]] = xor i1 [[PRED0:%.*]], true
 ; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
 ; CHECK:       A1:
 ; CHECK-NEXT:    br label [[IRR_GUARD1:%.*]]
 ; CHECK:       B1:
 ; CHECK-NEXT:    br i1 [[PRED2:%.*]], label [[IRR_GUARD1]], label [[A3:%.*]]
 ; CHECK:       B2:
-; CHECK-NEXT:    br i1 [[PRED3:%.*]], label [[B1:%.*]], label [[A3]]
+; CHECK-NEXT:    br i1 [[PRED3:%.*]], label [[IRR_GUARD1]], label [[A3]]
 ; CHECK:       A3:
 ; CHECK-NEXT:    br i1 [[PRED4:%.*]], label [[IRR_GUARD]], label [[EXIT:%.*]]
 ; CHECK:       A2:
-; CHECK-NEXT:    br i1 [[PRED5:%.*]], label [[A1:%.*]], label [[EXIT]]
+; CHECK-NEXT:    br i1 [[PRED5:%.*]], label [[IRR_GUARD]], label [[EXIT]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_A2:%.*]] = phi i1 [ true, [[A3]] ], [ [[PRED0_INV]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    br i1 [[GUARD_A2]], label [[A2:%.*]], label [[A1]]
+; CHECK-NEXT:    [[GUARD_A1:%.*]] = phi i1 [ true, [[A2:%.*]] ], [ [[PRED0:%.*]], [[ENTRY:%.*]] ], [ false, [[A3]] ]
+; CHECK-NEXT:    br i1 [[GUARD_A1]], label [[A1:%.*]], label [[A2]]
 ; CHECK:       irr.guard1:
-; CHECK-NEXT:    [[GUARD_B2:%.*]] = phi i1 [ true, [[B1]] ], [ [[PRED1_INV]], [[A1]] ]
-; CHECK-NEXT:    br i1 [[GUARD_B2]], label [[B2:%.*]], label [[B1]]
+; CHECK-NEXT:    [[GUARD_B1:%.*]] = phi i1 [ true, [[B2:%.*]] ], [ [[PRED1:%.*]], [[A1]] ], [ false, [[B1:%.*]] ]
+; CHECK-NEXT:    br i1 [[GUARD_B1]], label [[B1]], label [[B2]]
 ;
 entry:
   br i1 %Pred0, label %A1, label %A2
@@ -53,8 +50,6 @@ exit:
 define void @nested_irr_in_loop(i1 %Pred0, i1 %Pred1, i1 %Pred2, i1 %Pred3, i1 %Pred4, i1 %Pred5, i1 %Pred6) {
 ; CHECK-LABEL: @nested_irr_in_loop(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PRED1_INV:%.*]] = xor i1 [[PRED1:%.*]], true
-; CHECK-NEXT:    [[PRED0_INV:%.*]] = xor i1 [[PRED0:%.*]], true
 ; CHECK-NEXT:    br label [[H1:%.*]]
 ; CHECK:       H1:
 ; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
@@ -63,21 +58,21 @@ define void @nested_irr_in_loop(i1 %Pred0, i1 %Pred1, i1 %Pred2, i1 %Pred3, i1 %
 ; CHECK:       B1:
 ; CHECK-NEXT:    br i1 [[PRED2:%.*]], label [[IRR_GUARD1]], label [[A3:%.*]]
 ; CHECK:       B2:
-; CHECK-NEXT:    br i1 [[PRED3:%.*]], label [[B1:%.*]], label [[A3]]
+; CHECK-NEXT:    br i1 [[PRED3:%.*]], label [[IRR_GUARD1]], label [[A3]]
 ; CHECK:       A3:
 ; CHECK-NEXT:    br i1 [[PRED4:%.*]], label [[IRR_GUARD]], label [[L1:%.*]]
 ; CHECK:       A2:
-; CHECK-NEXT:    br i1 [[PRED5:%.*]], label [[A1:%.*]], label [[L1]]
+; CHECK-NEXT:    br i1 [[PRED5:%.*]], label [[IRR_GUARD]], label [[L1]]
 ; CHECK:       L1:
 ; CHECK-NEXT:    br i1 [[PRED6:%.*]], label [[EXIT:%.*]], label [[H1]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_A2:%.*]] = phi i1 [ true, [[A3]] ], [ [[PRED0_INV]], [[H1]] ]
-; CHECK-NEXT:    br i1 [[GUARD_A2]], label [[A2:%.*]], label [[A1]]
+; CHECK-NEXT:    [[GUARD_A1:%.*]] = phi i1 [ true, [[A2:%.*]] ], [ [[PRED0:%.*]], [[H1]] ], [ false, [[A3]] ]
+; CHECK-NEXT:    br i1 [[GUARD_A1]], label [[A1:%.*]], label [[A2]]
 ; CHECK:       irr.guard1:
-; CHECK-NEXT:    [[GUARD_B2:%.*]] = phi i1 [ true, [[B1]] ], [ [[PRED1_INV]], [[A1]] ]
-; CHECK-NEXT:    br i1 [[GUARD_B2]], label [[B2:%.*]], label [[B1]]
+; CHECK-NEXT:    [[GUARD_B1:%.*]] = phi i1 [ true, [[B2:%.*]] ], [ [[PRED1:%.*]], [[A1]] ], [ false, [[B1:%.*]] ]
+; CHECK-NEXT:    br i1 [[GUARD_B1]], label [[B1]], label [[B2]]
 ;
 entry:
   br label %H1
@@ -110,7 +105,6 @@ exit:
 define void @loop_in_irr(i1 %Pred0, i1 %Pred1, i1 %Pred2) {
 ; CHECK-LABEL: @loop_in_irr(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PRED0_INV:%.*]] = xor i1 [[PRED0:%.*]], true
 ; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
 ; CHECK:       A1:
 ; CHECK-NEXT:    br label [[H1:%.*]]
@@ -121,12 +115,12 @@ define void @loop_in_irr(i1 %Pred0, i1 %Pred1, i1 %Pred2) {
 ; CHECK:       A3:
 ; CHECK-NEXT:    br i1 [[PRED2:%.*]], label [[IRR_GUARD]], label [[EXIT:%.*]]
 ; CHECK:       A2:
-; CHECK-NEXT:    br label [[A1:%.*]]
+; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_A2:%.*]] = phi i1 [ true, [[A3]] ], [ [[PRED0_INV]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    br i1 [[GUARD_A2]], label [[A2:%.*]], label [[A1]]
+; CHECK-NEXT:    [[GUARD_A1:%.*]] = phi i1 [ true, [[A2:%.*]] ], [ [[PRED0:%.*]], [[ENTRY:%.*]] ], [ false, [[A3]] ]
+; CHECK-NEXT:    br i1 [[GUARD_A1]], label [[A1:%.*]], label [[A2]]
 ;
 entry:
   br i1 %Pred0, label %A1, label %A2
@@ -150,65 +144,26 @@ exit:
   ret void
 }
 
-define void @loop_in_irr_shared_entry(i1 %Pred0, i1 %Pred1, i1 %Pred2) {
-; CHECK-LABEL: @loop_in_irr_shared_entry(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PRED0_INV:%.*]] = xor i1 [[PRED0:%.*]], true
-; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
-; CHECK:       H1:
-; CHECK-NEXT:    br label [[L1:%.*]]
-; CHECK:       L1:
-; CHECK-NEXT:    br i1 [[PRED1:%.*]], label [[H1:%.*]], label [[A3:%.*]]
-; CHECK:       A3:
-; CHECK-NEXT:    br i1 [[PRED2:%.*]], label [[IRR_GUARD]], label [[EXIT:%.*]]
-; CHECK:       A2:
-; CHECK-NEXT:    br label [[H1]]
-; CHECK:       exit:
-; CHECK-NEXT:    ret void
-; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_A2:%.*]] = phi i1 [ true, [[A3]] ], [ [[PRED0_INV]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    br i1 [[GUARD_A2]], label [[A2:%.*]], label [[H1]]
-;
-entry:
-  br i1 %Pred0, label %H1, label %A2
-
-H1:
-  br label %L1
-
-L1:
-  br i1 %Pred1, label %H1, label %A3
-
-A3:
-  br i1 %Pred2, label %A2, label %exit
-
-A2:
-  br label %H1
-
-exit:
-  ret void
-}
-
 define void @loop_in_irr_shared_header(i1 %Pred0, i1 %Pred1, i1 %Pred2) {
 ; CHECK-LABEL: @loop_in_irr_shared_header(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PRED0_INV:%.*]] = xor i1 [[PRED0:%.*]], true
 ; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
 ; CHECK:       H1:
 ; CHECK-NEXT:    br label [[L1:%.*]]
 ; CHECK:       L1:
 ; CHECK-NEXT:    br i1 [[PRED1:%.*]], label [[IRR_GUARD]], label [[A3:%.*]]
 ; CHECK:       A3:
-; CHECK-NEXT:    br i1 [[PRED2:%.*]], label [[A2:%.*]], label [[EXIT:%.*]]
+; CHECK-NEXT:    br i1 [[PRED2:%.*]], label [[IRR_GUARD]], label [[EXIT:%.*]]
 ; CHECK:       A2:
 ; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_H1:%.*]] = phi i1 [ true, [[A2]] ], [ true, [[L1]] ], [ [[PRED0_INV]], [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[GUARD_H1:%.*]] = phi i1 [ true, [[A2:%.*]] ], [ true, [[L1]] ], [ [[PRED0:%.*]], [[ENTRY:%.*]] ], [ false, [[A3]] ]
 ; CHECK-NEXT:    br i1 [[GUARD_H1]], label [[H1:%.*]], label [[A2]]
 ;
 entry:
-  br i1 %Pred0, label %A2, label %H1
+  br i1 %Pred0, label %H1, label %A2
 
 H1:
   br label %L1
@@ -226,81 +181,36 @@ exit:
   ret void
 }
 
-define void @loop_irr_loop_shared_header(i1 %Pred0, i1 %Pred1, i1 %Pred2, i1 %Pred3) {
-; CHECK-LABEL: @loop_irr_loop_shared_header(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PRED0_INV:%.*]] = xor i1 [[PRED0:%.*]], true
-; CHECK-NEXT:    br label [[H2:%.*]]
-; CHECK:       H2:
-; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
-; CHECK:       H1:
-; CHECK-NEXT:    br i1 [[PRED1:%.*]], label [[A3:%.*]], label [[IRR_GUARD]]
-; CHECK:       A3:
-; CHECK-NEXT:    br i1 [[PRED2:%.*]], label [[A2:%.*]], label [[L2:%.*]]
-; CHECK:       A2:
-; CHECK-NEXT:    br label [[IRR_GUARD]]
-; CHECK:       L2:
-; CHECK-NEXT:    br i1 [[PRED3:%.*]], label [[H2]], label [[EXIT:%.*]]
-; CHECK:       exit:
-; CHECK-NEXT:    ret void
-; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_H1:%.*]] = phi i1 [ true, [[A2]] ], [ true, [[H1:%.*]] ], [ [[PRED0_INV]], [[H2]] ]
-; CHECK-NEXT:    br i1 [[GUARD_H1]], label [[H1]], label [[A2]]
-;
-entry:
-  br label %H2
-
-H2:
-  br i1 %Pred0, label %A2, label %H1
-
-H1:
-  br i1 %Pred1, label %A3, label %H1
-
-A3:
-  br i1 %Pred2, label %A2, label %L2
-
-A2:
-  br label %H1
-
-L2:
-  br i1 %Pred3, label %H2, label %exit
-
-exit:
-  ret void
-}
-
 define void @siblings_top_level(i1 %Pred0, i1 %Pred1, i1 %Pred2, i1 %Pred3, i1 %Pred4, i1 %Pred5, i1 %Pred6) {
 ; CHECK-LABEL: @siblings_top_level(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PRED4_INV:%.*]] = xor i1 [[PRED4:%.*]], true
-; CHECK-NEXT:    [[PRED1_INV:%.*]] = xor i1 [[PRED1:%.*]], true
 ; CHECK-NEXT:    br i1 [[PRED0:%.*]], label [[H1:%.*]], label [[FORK1:%.*]]
 ; CHECK:       H1:
-; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
+; CHECK-NEXT:    br label [[IRR_GUARD1:%.*]]
 ; CHECK:       A1:
-; CHECK-NEXT:    br label [[IRR_GUARD]]
+; CHECK-NEXT:    br label [[IRR_GUARD1]]
 ; CHECK:       A2:
-; CHECK-NEXT:    br i1 [[PRED2:%.*]], label [[A1:%.*]], label [[L1:%.*]]
+; CHECK-NEXT:    br i1 [[PRED2:%.*]], label [[IRR_GUARD1]], label [[L1:%.*]]
 ; CHECK:       L1:
 ; CHECK-NEXT:    br i1 [[PRED3:%.*]], label [[H1]], label [[EXIT:%.*]]
 ; CHECK:       fork1:
-; CHECK-NEXT:    br label [[IRR_GUARD1:%.*]]
+; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
 ; CHECK:       B1:
 ; CHECK-NEXT:    br label [[H2:%.*]]
 ; CHECK:       H2:
 ; CHECK-NEXT:    br label [[L2:%.*]]
 ; CHECK:       L2:
-; CHECK-NEXT:    br i1 [[PRED5:%.*]], label [[H2]], label [[IRR_GUARD1]]
+; CHECK-NEXT:    br i1 [[PRED5:%.*]], label [[H2]], label [[IRR_GUARD]]
 ; CHECK:       B2:
-; CHECK-NEXT:    br i1 [[PRED6:%.*]], label [[B1:%.*]], label [[EXIT]]
+; CHECK-NEXT:    br i1 [[PRED6:%.*]], label [[IRR_GUARD]], label [[EXIT]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_A2:%.*]] = phi i1 [ true, [[A1]] ], [ [[PRED1_INV]], [[H1]] ]
-; CHECK-NEXT:    br i1 [[GUARD_A2]], label [[A2:%.*]], label [[A1]]
+; CHECK-NEXT:    [[GUARD_B1:%.*]] = phi i1 [ true, [[B2:%.*]] ], [ [[PRED4:%.*]], [[FORK1]] ], [ false, [[L2]] ]
+; CHECK-NEXT:    br i1 [[GUARD_B1]], label [[B1:%.*]], label [[B2]]
 ; CHECK:       irr.guard1:
-; CHECK-NEXT:    [[GUARD_B2:%.*]] = phi i1 [ true, [[L2]] ], [ [[PRED4_INV]], [[FORK1]] ]
-; CHECK-NEXT:    br i1 [[GUARD_B2]], label [[B2:%.*]], label [[B1]]
+; CHECK-NEXT:    [[GUARD_A1:%.*]] = phi i1 [ true, [[A2:%.*]] ], [ [[PRED1:%.*]], [[H1]] ], [ false, [[A1:%.*]] ]
+; CHECK-NEXT:    br i1 [[GUARD_A1]], label [[A1]], label [[A2]]
 ;
 entry:
   br i1 %Pred0, label %H1, label %fork1
@@ -339,39 +249,37 @@ exit:
 define void @siblings_in_loop(i1 %Pred0, i1 %Pred1, i1 %Pred2, i1 %Pred3, i1 %Pred4, i1 %Pred5, i1 %Pred6, i1 %Pred7) {
 ; CHECK-LABEL: @siblings_in_loop(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PRED4_INV:%.*]] = xor i1 [[PRED4:%.*]], true
-; CHECK-NEXT:    [[PRED1_INV:%.*]] = xor i1 [[PRED1:%.*]], true
 ; CHECK-NEXT:    br label [[H0:%.*]]
 ; CHECK:       H0:
 ; CHECK-NEXT:    br i1 [[PRED0:%.*]], label [[H1:%.*]], label [[FORK1:%.*]]
 ; CHECK:       H1:
-; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
+; CHECK-NEXT:    br label [[IRR_GUARD1:%.*]]
 ; CHECK:       A1:
-; CHECK-NEXT:    br label [[IRR_GUARD]]
+; CHECK-NEXT:    br label [[IRR_GUARD1]]
 ; CHECK:       A2:
-; CHECK-NEXT:    br i1 [[PRED2:%.*]], label [[A1:%.*]], label [[L1:%.*]]
+; CHECK-NEXT:    br i1 [[PRED2:%.*]], label [[IRR_GUARD1]], label [[L1:%.*]]
 ; CHECK:       L1:
 ; CHECK-NEXT:    br i1 [[PRED3:%.*]], label [[H1]], label [[L0:%.*]]
 ; CHECK:       fork1:
-; CHECK-NEXT:    br label [[IRR_GUARD1:%.*]]
+; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
 ; CHECK:       B1:
 ; CHECK-NEXT:    br label [[H2:%.*]]
 ; CHECK:       H2:
 ; CHECK-NEXT:    br label [[L2:%.*]]
 ; CHECK:       L2:
-; CHECK-NEXT:    br i1 [[PRED5:%.*]], label [[H2]], label [[IRR_GUARD1]]
+; CHECK-NEXT:    br i1 [[PRED5:%.*]], label [[H2]], label [[IRR_GUARD]]
 ; CHECK:       B2:
-; CHECK-NEXT:    br i1 [[PRED6:%.*]], label [[B1:%.*]], label [[L0]]
+; CHECK-NEXT:    br i1 [[PRED6:%.*]], label [[IRR_GUARD]], label [[L0]]
 ; CHECK:       L0:
 ; CHECK-NEXT:    br i1 [[PRED7:%.*]], label [[EXIT:%.*]], label [[H0]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_A2:%.*]] = phi i1 [ true, [[A1]] ], [ [[PRED1_INV]], [[H1]] ]
-; CHECK-NEXT:    br i1 [[GUARD_A2]], label [[A2:%.*]], label [[A1]]
+; CHECK-NEXT:    [[GUARD_B1:%.*]] = phi i1 [ true, [[B2:%.*]] ], [ [[PRED4:%.*]], [[FORK1]] ], [ false, [[L2]] ]
+; CHECK-NEXT:    br i1 [[GUARD_B1]], label [[B1:%.*]], label [[B2]]
 ; CHECK:       irr.guard1:
-; CHECK-NEXT:    [[GUARD_B2:%.*]] = phi i1 [ true, [[L2]] ], [ [[PRED4_INV]], [[FORK1]] ]
-; CHECK-NEXT:    br i1 [[GUARD_B2]], label [[B2:%.*]], label [[B1]]
+; CHECK-NEXT:    [[GUARD_A1:%.*]] = phi i1 [ true, [[A2:%.*]] ], [ [[PRED1:%.*]], [[H1]] ], [ false, [[A1:%.*]] ]
+; CHECK-NEXT:    br i1 [[GUARD_A1]], label [[A1]], label [[A2]]
 ;
 entry:
   br label %H0
@@ -413,8 +321,8 @@ exit:
   ret void
 }
 
-define void @irr_in_irr_shared_entry(i1 %Pred0, i1 %Pred1, i1 %Pred2, i1 %Pred3, i1 %Pred4, i1 %Pred5, i1 %Pred6, i1 %Pred7, i1 %Pred8, i1 %Pred9, i1 %Pred10, i1 %Pred11, i1 %Pred12, i1 %Pred13) {
-; CHECK-LABEL: @irr_in_irr_shared_entry(
+define void @irreducible_mountain_bug(i1 %Pred0, i1 %Pred1, i1 %Pred2, i1 %Pred3, i1 %Pred4, i1 %Pred5, i1 %Pred6, i1 %Pred7, i1 %Pred8, i1 %Pred9, i1 %Pred10, i1 %Pred11, i1 %Pred12, i1 %Pred13) {
+; CHECK-LABEL: @irreducible_mountain_bug(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    br i1 [[PRED0:%.*]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
 ; CHECK:       if.end:
@@ -430,13 +338,13 @@ define void @irr_in_irr_shared_entry(i1 %Pred0, i1 %Pred1, i1 %Pred2, i1 %Pred3,
 ; CHECK:       while.cond:
 ; CHECK-NEXT:    br i1 [[PRED3:%.*]], label [[IRR_GUARD:%.*]], label [[LOR_RHS:%.*]]
 ; CHECK:       cond.true49:
-; CHECK-NEXT:    br i1 [[PRED4:%.*]], label [[IF_THEN69:%.*]], label [[IRR_GUARD1:%.*]]
+; CHECK-NEXT:    br i1 [[PRED4:%.*]], label [[IF_THEN69:%.*]], label [[WHILE_BODY63:%.*]]
 ; CHECK:       while.body63:
 ; CHECK-NEXT:    br i1 [[PRED5:%.*]], label [[EXIT:%.*]], label [[WHILE_COND47:%.*]]
 ; CHECK:       while.cond47:
-; CHECK-NEXT:    br i1 [[PRED6:%.*]], label [[COND_TRUE49:%.*]], label [[IRR_GUARD]]
+; CHECK-NEXT:    br label [[IRR_GUARD]]
 ; CHECK:       cond.end61:
-; CHECK-NEXT:    br i1 [[PRED7:%.*]], label [[IRR_GUARD1]], label [[WHILE_COND]]
+; CHECK-NEXT:    br i1 [[PRED7:%.*]], label [[WHILE_BODY63]], label [[WHILE_COND]]
 ; CHECK:       if.then69:
 ; CHECK-NEXT:    br i1 [[PRED8:%.*]], label [[EXIT]], label [[WHILE_COND]]
 ; CHECK:       lor.rhs:
@@ -458,11 +366,8 @@ define void @irr_in_irr_shared_entry(i1 %Pred0, i1 %Pred1, i1 %Pred2, i1 %Pred3,
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_COND_END61:%.*]] = phi i1 [ true, [[WHILE_COND47]] ], [ true, [[LOR_RHS]] ], [ false, [[WHILE_COND]] ]
-; CHECK-NEXT:    br i1 [[GUARD_COND_END61]], label [[COND_END61:%.*]], label [[IRR_GUARD1]]
-; CHECK:       irr.guard1:
-; CHECK-NEXT:    [[GUARD_WHILE_BODY63:%.*]] = phi i1 [ true, [[COND_TRUE49]] ], [ true, [[COND_END61]] ], [ false, [[IRR_GUARD]] ]
-; CHECK-NEXT:    br i1 [[GUARD_WHILE_BODY63]], label [[WHILE_BODY63:%.*]], label [[COND_TRUE49]]
+; CHECK-NEXT:    [[GUARD_COND_TRUE49:%.*]] = phi i1 [ [[PRED6:%.*]], [[WHILE_COND47]] ], [ true, [[WHILE_COND]] ], [ false, [[LOR_RHS]] ]
+; CHECK-NEXT:    br i1 [[GUARD_COND_TRUE49]], label [[COND_TRUE49:%.*]], label [[COND_END61:%.*]]
 ;
 entry:
   br i1 %Pred0, label %if.end, label %if.then

diff  --git a/llvm/test/Transforms/FixIrreducible/switch.ll b/llvm/test/Transforms/FixIrreducible/switch.ll
index 4d3d9498b284d2..f648b597b84695 100644
--- a/llvm/test/Transforms/FixIrreducible/switch.ll
+++ b/llvm/test/Transforms/FixIrreducible/switch.ll
@@ -1,12 +1,10 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
 ; RUN: opt < %s -lowerswitch -fix-irreducible --verify-loop-info -S | FileCheck %s
 ; RUN: opt < %s -passes='lower-switch,fix-irreducible,verify<loops>' -S | FileCheck %s
-; RUN: opt < %s -passes='lower-switch,verify<loops>,fix-irreducible,verify<loops>' -S | FileCheck %s
 
 define void @loop_1(i32 %Value, i1 %PredEntry, i1 %PredD) {
 ; CHECK-LABEL: @loop_1(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[PREDENTRY_INV:%.*]] = xor i1 [[PREDENTRY:%.*]], true
 ; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
 ; CHECK:       A:
 ; CHECK-NEXT:    br label [[IRR_GUARD]]
@@ -20,12 +18,12 @@ define void @loop_1(i32 %Value, i1 %PredEntry, i1 %PredD) {
 ; CHECK-NEXT:    br i1 [[SWITCHLEAF2]], label [[IRR_GUARD]], label [[EXIT:%.*]]
 ; CHECK:       LeafBlock:
 ; CHECK-NEXT:    [[SWITCHLEAF:%.*]] = icmp eq i32 [[VALUE]], 0
-; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[A:%.*]], label [[EXIT]]
+; CHECK-NEXT:    br i1 [[SWITCHLEAF]], label [[IRR_GUARD]], label [[EXIT]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_B:%.*]] = phi i1 [ true, [[LEAFBLOCK1]] ], [ true, [[A]] ], [ [[PREDENTRY_INV]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    br i1 [[GUARD_B]], label [[B:%.*]], label [[A]]
+; CHECK-NEXT:    [[GUARD_A:%.*]] = phi i1 [ true, [[LEAFBLOCK]] ], [ [[PREDENTRY:%.*]], [[ENTRY:%.*]] ], [ false, [[LEAFBLOCK1]] ], [ false, [[A:%.*]] ]
+; CHECK-NEXT:    br i1 [[GUARD_A]], label [[A]], label [[B:%.*]]
 ;
 entry:
   br i1 %PredEntry, label %A, label %B

diff  --git a/llvm/test/Transforms/FixIrreducible/unreachable.ll b/llvm/test/Transforms/FixIrreducible/unreachable.ll
index cc9a29b2a8d711..e61bd2b5a0ae45 100644
--- a/llvm/test/Transforms/FixIrreducible/unreachable.ll
+++ b/llvm/test/Transforms/FixIrreducible/unreachable.ll
@@ -1,7 +1,6 @@
 ; NOTE: Do not autogenerate
 ; RUN: opt < %s -fix-irreducible --verify-loop-info -S | FileCheck %s
 ; RUN: opt < %s -passes='fix-irreducible,verify<loops>' -S | FileCheck %s
-; RUN: opt < %s -passes='verify<loops>,fix-irreducible,verify<loops>' -S | FileCheck %s
 
 ; CHECK-LABEL: @unreachable(
 ; CHECK: entry:

diff  --git a/llvm/test/Transforms/StructurizeCFG/workarounds/needs-fix-reducible.ll b/llvm/test/Transforms/StructurizeCFG/workarounds/needs-fix-reducible.ll
index d09d7454793bbf..172a0da8d2d4bc 100644
--- a/llvm/test/Transforms/StructurizeCFG/workarounds/needs-fix-reducible.ll
+++ b/llvm/test/Transforms/StructurizeCFG/workarounds/needs-fix-reducible.ll
@@ -9,49 +9,37 @@ define void @irreducible(i1 %PredEntry, i1 %PredB1, i1 %PredB2, i1 %PredB3, i1 %
 ; CHECK-LABEL: @irreducible(
 ; CHECK-NEXT:  entry:
 ; CHECK-NEXT:    [[PREDB2_INV:%.*]] = xor i1 [[PREDB2:%.*]], true
-; CHECK-NEXT:    [[PREDENTRY_INV:%.*]] = xor i1 [[PREDENTRY:%.*]], true
+; CHECK-NEXT:    [[PREDB1_INV:%.*]] = xor i1 [[PREDB1:%.*]], true
 ; CHECK-NEXT:    br label [[IRR_GUARD:%.*]]
-; CHECK:       Flow4:
-; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ true, [[B3:%.*]] ], [ undef, [[B2:%.*]] ]
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i1 [ [[PREDB3:%.*]], [[B3]] ], [ true, [[B2]] ]
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i1 [ [[PREDB3]], [[B3]] ], [ false, [[B2]] ]
-; CHECK-NEXT:    br label [[FLOW3:%.*]]
+; CHECK:       Flow:
+; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ [[PREDB4:%.*]], [[B4:%.*]] ], [ false, [[IRR_GUARD]] ]
+; CHECK-NEXT:    [[TMP1:%.*]] = phi i1 [ false, [[B4]] ], [ true, [[IRR_GUARD]] ]
+; CHECK-NEXT:    br i1 [[TMP1]], label [[B1:%.*]], label [[FLOW1:%.*]]
 ; CHECK:       B1:
-; CHECK-NEXT:    br label [[FLOW5:%.*]]
-; CHECK:       Flow2:
-; CHECK-NEXT:    [[TMP3:%.*]] = phi i1 [ [[TMP9:%.*]], [[FLOW5]] ], [ [[TMP11:%.*]], [[FLOW:%.*]] ]
-; CHECK-NEXT:    [[TMP4:%.*]] = phi i1 [ [[TMP10:%.*]], [[FLOW5]] ], [ [[TMP12:%.*]], [[FLOW]] ]
-; CHECK-NEXT:    [[TMP5:%.*]] = phi i1 [ [[TMP7:%.*]], [[FLOW5]] ], [ true, [[FLOW]] ]
-; CHECK-NEXT:    br i1 true, label [[FLOW6:%.*]], label [[FLOW]]
+; CHECK-NEXT:    br label [[FLOW1]]
+; CHECK:       Flow1:
+; CHECK-NEXT:    [[TMP2:%.*]] = phi i1 [ [[PREDB1_INV]], [[B1]] ], [ [[TMP0]], [[FLOW:%.*]] ]
+; CHECK-NEXT:    br i1 [[TMP2]], label [[B2:%.*]], label [[FLOW2:%.*]]
 ; CHECK:       B2:
-; CHECK-NEXT:    br i1 [[PREDB2_INV]], label [[B3]], label [[FLOW4:%.*]]
-; CHECK:       Flow3:
-; CHECK-NEXT:    [[TMP6:%.*]] = phi i1 [ [[TMP0]], [[FLOW4]] ], [ undef, [[IRR_GUARD1:%.*]] ]
-; CHECK-NEXT:    [[TMP7]] = phi i1 [ [[TMP1]], [[FLOW4]] ], [ true, [[IRR_GUARD1]] ]
-; CHECK-NEXT:    [[TMP8:%.*]] = phi i1 [ [[TMP2]], [[FLOW4]] ], [ true, [[IRR_GUARD1]] ]
-; CHECK-NEXT:    br i1 [[TMP8]], label [[B1:%.*]], label [[FLOW5]]
+; CHECK-NEXT:    br i1 [[PREDB2_INV]], label [[B3:%.*]], label [[FLOW3:%.*]]
+; CHECK:       Flow2:
+; CHECK-NEXT:    [[TMP3:%.*]] = phi i1 [ [[TMP5:%.*]], [[FLOW3]] ], [ undef, [[FLOW1]] ]
+; CHECK-NEXT:    [[TMP4:%.*]] = phi i1 [ [[TMP6:%.*]], [[FLOW3]] ], [ true, [[FLOW1]] ]
+; CHECK-NEXT:    br i1 [[TMP4]], label [[EXIT:%.*]], label [[IRR_GUARD]]
 ; CHECK:       B3:
-; CHECK-NEXT:    br label [[FLOW4]]
+; CHECK-NEXT:    br label [[FLOW3]]
 ; CHECK:       B4:
 ; CHECK-NEXT:    br label [[FLOW]]
-; CHECK:       Flow5:
-; CHECK-NEXT:    [[TMP9]] = phi i1 [ undef, [[B1]] ], [ [[TMP6]], [[FLOW3]] ]
-; CHECK-NEXT:    [[TMP10]] = phi i1 [ true, [[B1]] ], [ undef, [[FLOW3]] ]
-; CHECK-NEXT:    br label [[FLOW2:%.*]]
-; CHECK:       Flow6:
-; CHECK-NEXT:    br i1 [[TMP5]], label [[EXIT:%.*]], label [[IRR_GUARD]]
+; CHECK:       Flow3:
+; CHECK-NEXT:    [[TMP5]] = phi i1 [ [[PREDB3:%.*]], [[B3]] ], [ undef, [[B2]] ]
+; CHECK-NEXT:    [[TMP6]] = phi i1 [ false, [[B3]] ], [ true, [[B2]] ]
+; CHECK-NEXT:    br label [[FLOW2]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_B4:%.*]] = phi i1 [ [[PREDENTRY_INV]], [[ENTRY:%.*]] ], [ [[TMP3]], [[FLOW6]] ]
-; CHECK-NEXT:    br i1 [[GUARD_B4]], label [[B4:%.*]], label [[FLOW]]
-; CHECK:       Flow:
-; CHECK-NEXT:    [[TMP11]] = phi i1 [ [[TMP3]], [[FLOW2]] ], [ undef, [[B4]] ], [ undef, [[IRR_GUARD]] ]
-; CHECK-NEXT:    [[TMP12]] = phi i1 [ [[TMP4]], [[FLOW2]] ], [ true, [[B4]] ], [ false, [[IRR_GUARD]] ]
-; CHECK-NEXT:    [[TMP13:%.*]] = phi i1 [ false, [[FLOW2]] ], [ [[PREDB4:%.*]], [[B4]] ], [ true, [[IRR_GUARD]] ]
-; CHECK-NEXT:    br i1 [[TMP13]], label [[IRR_GUARD1]], label [[FLOW2]]
-; CHECK:       irr.guard1:
-; CHECK-NEXT:    br i1 [[TMP12]], label [[B2]], label [[FLOW3]]
+; CHECK-NEXT:    [[GUARD_B1:%.*]] = phi i1 [ [[PREDENTRY:%.*]], [[ENTRY:%.*]] ], [ [[TMP3]], [[FLOW2]] ]
+; CHECK-NEXT:    [[GUARD_B1_INV:%.*]] = xor i1 [[GUARD_B1]], true
+; CHECK-NEXT:    br i1 [[GUARD_B1_INV]], label [[B4]], label [[FLOW]]
 ;
 {
 entry:

diff  --git a/llvm/test/Transforms/StructurizeCFG/workarounds/needs-fr-ule.ll b/llvm/test/Transforms/StructurizeCFG/workarounds/needs-fr-ule.ll
index 912beed6b2eed3..f588d3fe7cef3e 100644
--- a/llvm/test/Transforms/StructurizeCFG/workarounds/needs-fr-ule.ll
+++ b/llvm/test/Transforms/StructurizeCFG/workarounds/needs-fr-ule.ll
@@ -8,138 +8,126 @@ define void @irreducible_mountain_bug(i1 %Pred0, i1 %Pred1, i1 %Pred2, i1 %Pred3
 ; CHECK-NEXT:    [[PRED2_INV:%.*]] = xor i1 [[PRED2:%.*]], true
 ; CHECK-NEXT:    [[PRED3_INV:%.*]] = xor i1 [[PRED3:%.*]], true
 ; CHECK-NEXT:    [[PRED5_INV:%.*]] = xor i1 [[PRED5:%.*]], true
+; CHECK-NEXT:    [[PRED4_INV:%.*]] = xor i1 [[PRED4:%.*]], true
 ; CHECK-NEXT:    [[PRED10_INV:%.*]] = xor i1 [[PRED10:%.*]], true
 ; CHECK-NEXT:    [[PRED11_INV:%.*]] = xor i1 [[PRED11:%.*]], true
 ; CHECK-NEXT:    [[PRED12_INV:%.*]] = xor i1 [[PRED12:%.*]], true
 ; CHECK-NEXT:    [[PRED13_INV:%.*]] = xor i1 [[PRED13:%.*]], true
-; CHECK-NEXT:    br i1 [[PRED0_INV]], label [[IF_THEN:%.*]], label [[FLOW22:%.*]]
-; CHECK:       Flow22:
-; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ false, [[FLOW5:%.*]] ], [ true, [[ENTRY:%.*]] ]
-; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_END:%.*]], label [[FLOW23:%.*]]
+; CHECK-NEXT:    br i1 [[PRED0_INV]], label [[IF_THEN:%.*]], label [[FLOW19:%.*]]
+; CHECK:       Flow19:
+; CHECK-NEXT:    [[TMP0:%.*]] = phi i1 [ false, [[FLOW3:%.*]] ], [ true, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_END:%.*]], label [[FLOW20:%.*]]
 ; CHECK:       if.end:
-; CHECK-NEXT:    br i1 [[PRED1_INV]], label [[IF_ELSE:%.*]], label [[FLOW21:%.*]]
-; CHECK:       Flow21:
+; CHECK-NEXT:    br i1 [[PRED1_INV]], label [[IF_ELSE:%.*]], label [[FLOW18:%.*]]
+; CHECK:       Flow18:
 ; CHECK-NEXT:    [[TMP1:%.*]] = phi i1 [ false, [[IF_ELSE]] ], [ true, [[IF_END]] ]
 ; CHECK-NEXT:    br i1 [[TMP1]], label [[IF_THEN7:%.*]], label [[IF_END16:%.*]]
 ; CHECK:       if.then7:
 ; CHECK-NEXT:    br label [[IF_END16]]
 ; CHECK:       if.else:
-; CHECK-NEXT:    br label [[FLOW21]]
-; CHECK:       Flow23:
+; CHECK-NEXT:    br label [[FLOW18]]
+; CHECK:       Flow20:
 ; CHECK-NEXT:    br label [[EXIT:%.*]]
 ; CHECK:       if.end16:
-; CHECK-NEXT:    br i1 [[PRED2_INV]], label [[IF_THEN39:%.*]], label [[FLOW19:%.*]]
-; CHECK:       Flow19:
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i1 [ false, [[FLOW7:%.*]] ], [ true, [[IF_END16]] ]
-; CHECK-NEXT:    br i1 [[TMP2]], label [[WHILE_COND_PREHEADER:%.*]], label [[FLOW20:%.*]]
+; CHECK-NEXT:    br i1 [[PRED2_INV]], label [[IF_THEN39:%.*]], label [[FLOW16:%.*]]
+; CHECK:       Flow16:
+; CHECK-NEXT:    [[TMP2:%.*]] = phi i1 [ false, [[FLOW5:%.*]] ], [ true, [[IF_END16]] ]
+; CHECK-NEXT:    br i1 [[TMP2]], label [[WHILE_COND_PREHEADER:%.*]], label [[FLOW17:%.*]]
 ; CHECK:       while.cond.preheader:
 ; CHECK-NEXT:    br label [[WHILE_COND:%.*]]
-; CHECK:       Flow20:
-; CHECK-NEXT:    br label [[FLOW23]]
+; CHECK:       Flow17:
+; CHECK-NEXT:    br label [[FLOW20]]
 ; CHECK:       while.cond:
-; CHECK-NEXT:    br i1 [[PRED3_INV]], label [[LOR_RHS:%.*]], label [[FLOW15:%.*]]
-; CHECK:       Flow10:
-; CHECK-NEXT:    [[TMP3:%.*]] = phi i1 [ false, [[WHILE_COND47:%.*]] ], [ true, [[WHILE_BODY63:%.*]] ]
-; CHECK-NEXT:    [[TMP4:%.*]] = phi i1 [ [[PRED6:%.*]], [[WHILE_COND47]] ], [ false, [[WHILE_BODY63]] ]
-; CHECK-NEXT:    br label [[FLOW9:%.*]]
+; CHECK-NEXT:    br i1 [[PRED3_INV]], label [[LOR_RHS:%.*]], label [[FLOW12:%.*]]
+; CHECK:       Flow7:
+; CHECK-NEXT:    [[TMP3:%.*]] = phi i1 [ false, [[COND_END61:%.*]] ], [ undef, [[IRR_GUARD:%.*]] ]
+; CHECK-NEXT:    [[TMP4:%.*]] = phi i1 [ true, [[COND_END61]] ], [ undef, [[IRR_GUARD]] ]
+; CHECK-NEXT:    [[TMP5:%.*]] = phi i1 [ [[PRED7:%.*]], [[COND_END61]] ], [ false, [[IRR_GUARD]] ]
+; CHECK-NEXT:    [[TMP6:%.*]] = phi i1 [ false, [[COND_END61]] ], [ true, [[IRR_GUARD]] ]
+; CHECK-NEXT:    br i1 [[TMP6]], label [[COND_TRUE49:%.*]], label [[FLOW8:%.*]]
 ; CHECK:       cond.true49:
-; CHECK-NEXT:    br label [[FLOW11:%.*]]
+; CHECK-NEXT:    br label [[FLOW8]]
+; CHECK:       Flow8:
+; CHECK-NEXT:    [[TMP7:%.*]] = phi i1 [ false, [[COND_TRUE49]] ], [ [[TMP3]], [[FLOW7:%.*]] ]
+; CHECK-NEXT:    [[TMP8:%.*]] = phi i1 [ false, [[COND_TRUE49]] ], [ [[TMP4]], [[FLOW7]] ]
+; CHECK-NEXT:    [[TMP9:%.*]] = phi i1 [ [[PRED4_INV]], [[COND_TRUE49]] ], [ [[TMP5]], [[FLOW7]] ]
+; CHECK-NEXT:    br i1 [[TMP9]], label [[WHILE_BODY63:%.*]], label [[FLOW9:%.*]]
 ; CHECK:       while.body63:
-; CHECK-NEXT:    br i1 [[PRED5_INV]], label [[WHILE_COND47]], label [[FLOW10:%.*]]
+; CHECK-NEXT:    br i1 [[PRED5_INV]], label [[WHILE_COND47:%.*]], label [[FLOW10:%.*]]
 ; CHECK:       Flow9:
-; CHECK-NEXT:    [[TMP5:%.*]] = phi i1 [ [[TMP3]], [[FLOW10]] ], [ undef, [[IRR_GUARD1:%.*]] ]
-; CHECK-NEXT:    [[TMP6:%.*]] = phi i1 [ false, [[FLOW10]] ], [ undef, [[IRR_GUARD1]] ]
-; CHECK-NEXT:    [[TMP7:%.*]] = phi i1 [ true, [[FLOW10]] ], [ undef, [[IRR_GUARD1]] ]
-; CHECK-NEXT:    [[TMP8:%.*]] = phi i1 [ true, [[FLOW10]] ], [ undef, [[IRR_GUARD1]] ]
-; CHECK-NEXT:    [[TMP9:%.*]] = phi i1 [ [[TMP4]], [[FLOW10]] ], [ true, [[IRR_GUARD1]] ]
-; CHECK-NEXT:    br i1 [[TMP9]], label [[COND_TRUE49:%.*]], label [[FLOW11]]
+; CHECK-NEXT:    [[TMP10:%.*]] = phi i1 [ [[TMP22:%.*]], [[FLOW10]] ], [ undef, [[FLOW8]] ]
+; CHECK-NEXT:    [[TMP11:%.*]] = phi i1 [ true, [[FLOW10]] ], [ [[TMP7]], [[FLOW8]] ]
+; CHECK-NEXT:    [[TMP12:%.*]] = phi i1 [ false, [[FLOW10]] ], [ [[TMP8]], [[FLOW8]] ]
+; CHECK-NEXT:    [[TMP13:%.*]] = phi i1 [ false, [[FLOW10]] ], [ undef, [[FLOW8]] ]
+; CHECK-NEXT:    [[TMP14:%.*]] = phi i1 [ [[TMP23:%.*]], [[FLOW10]] ], [ true, [[FLOW8]] ]
+; CHECK-NEXT:    [[DOTINV11:%.*]] = xor i1 [[TMP11]], true
+; CHECK-NEXT:    [[DOTINV:%.*]] = xor i1 [[TMP12]], true
+; CHECK-NEXT:    br i1 [[TMP14]], label [[LOOP_EXIT_GUARD1:%.*]], label [[IRR_GUARD]]
 ; CHECK:       while.cond47:
 ; CHECK-NEXT:    br label [[FLOW10]]
 ; CHECK:       cond.end61:
-; CHECK-NEXT:    br label [[FLOW12:%.*]]
-; CHECK:       Flow17:
-; CHECK-NEXT:    [[TMP10:%.*]] = phi i1 [ [[TMP19:%.*]], [[FLOW18:%.*]] ], [ undef, [[LOOP_EXIT_GUARD2:%.*]] ]
-; CHECK-NEXT:    [[TMP11:%.*]] = phi i1 [ [[TMP20:%.*]], [[FLOW18]] ], [ [[DOTINV:%.*]], [[LOOP_EXIT_GUARD2]] ]
-; CHECK-NEXT:    br label [[FLOW16:%.*]]
+; CHECK-NEXT:    br label [[FLOW7]]
+; CHECK:       Flow14:
+; CHECK-NEXT:    [[TMP15:%.*]] = phi i1 [ [[TMP20:%.*]], [[FLOW15:%.*]] ], [ undef, [[LOOP_EXIT_GUARD1]] ]
+; CHECK-NEXT:    [[TMP16:%.*]] = phi i1 [ [[TMP21:%.*]], [[FLOW15]] ], [ [[DOTINV]], [[LOOP_EXIT_GUARD1]] ]
+; CHECK-NEXT:    br label [[FLOW13:%.*]]
 ; CHECK:       if.then69:
-; CHECK-NEXT:    br label [[FLOW18]]
-; CHECK:       lor.rhs:
 ; CHECK-NEXT:    br label [[FLOW15]]
+; CHECK:       lor.rhs:
+; CHECK-NEXT:    br label [[FLOW12]]
 ; CHECK:       while.end76:
-; CHECK-NEXT:    br label [[FLOW8:%.*]]
+; CHECK-NEXT:    br label [[FLOW6:%.*]]
 ; CHECK:       if.then39:
-; CHECK-NEXT:    br i1 [[PRED10_INV]], label [[IF_END_I145:%.*]], label [[FLOW7]]
+; CHECK-NEXT:    br i1 [[PRED10_INV]], label [[IF_END_I145:%.*]], label [[FLOW5]]
 ; CHECK:       if.end.i145:
-; CHECK-NEXT:    br i1 [[PRED11_INV]], label [[IF_END8_I149:%.*]], label [[FLOW6:%.*]]
+; CHECK-NEXT:    br i1 [[PRED11_INV]], label [[IF_END8_I149:%.*]], label [[FLOW4:%.*]]
 ; CHECK:       if.end8.i149:
-; CHECK-NEXT:    br label [[FLOW6]]
+; CHECK-NEXT:    br label [[FLOW4]]
 ; CHECK:       if.then:
-; CHECK-NEXT:    br i1 [[PRED12_INV]], label [[IF_END_I:%.*]], label [[FLOW5]]
+; CHECK-NEXT:    br i1 [[PRED12_INV]], label [[IF_END_I:%.*]], label [[FLOW3]]
 ; CHECK:       if.end.i:
 ; CHECK-NEXT:    br i1 [[PRED13_INV]], label [[IF_END8_I:%.*]], label [[FLOW:%.*]]
 ; CHECK:       if.end8.i:
 ; CHECK-NEXT:    br label [[FLOW]]
 ; CHECK:       Flow:
+; CHECK-NEXT:    br label [[FLOW3]]
+; CHECK:       Flow3:
+; CHECK-NEXT:    br label [[FLOW19]]
+; CHECK:       Flow4:
 ; CHECK-NEXT:    br label [[FLOW5]]
 ; CHECK:       Flow5:
-; CHECK-NEXT:    br label [[FLOW22]]
+; CHECK-NEXT:    br label [[FLOW16]]
 ; CHECK:       Flow6:
-; CHECK-NEXT:    br label [[FLOW7]]
-; CHECK:       Flow7:
-; CHECK-NEXT:    br label [[FLOW19]]
-; CHECK:       Flow8:
-; CHECK-NEXT:    br label [[FLOW20]]
+; CHECK-NEXT:    br label [[FLOW17]]
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret void
-; CHECK:       Flow15:
-; CHECK-NEXT:    [[TMP12:%.*]] = phi i1 [ true, [[LOR_RHS]] ], [ undef, [[WHILE_COND]] ]
-; CHECK-NEXT:    [[TMP13:%.*]] = phi i1 [ true, [[LOR_RHS]] ], [ false, [[WHILE_COND]] ]
-; CHECK-NEXT:    [[TMP14:%.*]] = phi i1 [ [[PRED9:%.*]], [[LOR_RHS]] ], [ true, [[WHILE_COND]] ]
-; CHECK-NEXT:    br i1 [[TMP14]], label [[IRR_GUARD:%.*]], label [[FLOW16]]
-; CHECK:       irr.guard:
-; CHECK-NEXT:    [[GUARD_COND_END61:%.*]] = phi i1 [ [[TMP28:%.*]], [[FLOW13:%.*]] ], [ [[TMP13]], [[FLOW15]] ]
-; CHECK-NEXT:    br i1 [[GUARD_COND_END61]], label [[COND_END61:%.*]], label [[FLOW12]]
 ; CHECK:       Flow12:
-; CHECK-NEXT:    [[TMP15:%.*]] = phi i1 [ false, [[COND_END61]] ], [ undef, [[IRR_GUARD]] ]
-; CHECK-NEXT:    [[TMP16:%.*]] = phi i1 [ true, [[COND_END61]] ], [ undef, [[IRR_GUARD]] ]
-; CHECK-NEXT:    [[TMP17:%.*]] = phi i1 [ true, [[COND_END61]] ], [ false, [[IRR_GUARD]] ]
-; CHECK-NEXT:    [[TMP18:%.*]] = phi i1 [ [[PRED7:%.*]], [[COND_END61]] ], [ true, [[IRR_GUARD]] ]
-; CHECK-NEXT:    br i1 [[TMP18]], label [[IRR_GUARD1]], label [[FLOW13]]
-; CHECK:       irr.guard1:
-; CHECK-NEXT:    [[GUARD_WHILE_BODY63:%.*]] = phi i1 [ [[TMP23:%.*]], [[FLOW11]] ], [ [[TMP17]], [[FLOW12]] ]
-; CHECK-NEXT:    br i1 [[GUARD_WHILE_BODY63]], label [[WHILE_BODY63]], label [[FLOW9]]
-; CHECK:       Flow18:
-; CHECK-NEXT:    [[TMP19]] = phi i1 [ false, [[IF_THEN69:%.*]] ], [ [[TMP31:%.*]], [[LOOP_EXIT_GUARD3:%.*]] ]
-; CHECK-NEXT:    [[TMP20]] = phi i1 [ [[PRED8:%.*]], [[IF_THEN69]] ], [ [[DOTINV]], [[LOOP_EXIT_GUARD3]] ]
-; CHECK-NEXT:    br label [[FLOW17:%.*]]
+; CHECK-NEXT:    [[TMP17:%.*]] = phi i1 [ true, [[LOR_RHS]] ], [ undef, [[WHILE_COND]] ]
+; CHECK-NEXT:    [[TMP18:%.*]] = phi i1 [ false, [[LOR_RHS]] ], [ true, [[WHILE_COND]] ]
+; CHECK-NEXT:    [[TMP19:%.*]] = phi i1 [ [[PRED9:%.*]], [[LOR_RHS]] ], [ [[PRED3]], [[WHILE_COND]] ]
+; CHECK-NEXT:    br i1 [[TMP19]], label [[IRR_GUARD]], label [[FLOW13]]
+; CHECK:       irr.guard:
+; CHECK-NEXT:    [[GUARD_COND_TRUE49:%.*]] = phi i1 [ [[TMP10]], [[FLOW9]] ], [ [[TMP18]], [[FLOW12]] ]
+; CHECK-NEXT:    [[GUARD_COND_TRUE49_INV:%.*]] = xor i1 [[GUARD_COND_TRUE49]], true
+; CHECK-NEXT:    br i1 [[GUARD_COND_TRUE49_INV]], label [[COND_END61]], label [[FLOW7]]
+; CHECK:       Flow15:
+; CHECK-NEXT:    [[TMP20]] = phi i1 [ false, [[IF_THEN69:%.*]] ], [ [[TMP13]], [[LOOP_EXIT_GUARD2:%.*]] ]
+; CHECK-NEXT:    [[TMP21]] = phi i1 [ [[PRED8:%.*]], [[IF_THEN69]] ], [ [[DOTINV]], [[LOOP_EXIT_GUARD2]] ]
+; CHECK-NEXT:    br label [[FLOW14:%.*]]
 ; CHECK:       loop.exit.guard:
-; CHECK-NEXT:    br i1 [[TMP21:%.*]], label [[WHILE_END76:%.*]], label [[FLOW8]]
-; CHECK:       Flow16:
-; CHECK-NEXT:    [[TMP21]] = phi i1 [ [[TMP10]], [[FLOW17]] ], [ [[TMP12]], [[FLOW15]] ]
-; CHECK-NEXT:    [[TMP22:%.*]] = phi i1 [ [[TMP11]], [[FLOW17]] ], [ true, [[FLOW15]] ]
-; CHECK-NEXT:    br i1 [[TMP22]], label [[LOOP_EXIT_GUARD:%.*]], label [[WHILE_COND]]
-; CHECK:       loop.exit.guard2:
-; CHECK-NEXT:    br i1 [[DOTINV]], label [[LOOP_EXIT_GUARD3]], label [[FLOW17]]
-; CHECK:       loop.exit.guard3:
-; CHECK-NEXT:    br i1 [[DOTINV14:%.*]], label [[IF_THEN69]], label [[FLOW18]]
-; CHECK:       Flow11:
-; CHECK-NEXT:    [[TMP23]] = phi i1 [ true, [[COND_TRUE49]] ], [ undef, [[FLOW9]] ]
-; CHECK-NEXT:    [[TMP24:%.*]] = phi i1 [ true, [[COND_TRUE49]] ], [ [[TMP5]], [[FLOW9]] ]
-; CHECK-NEXT:    [[TMP25:%.*]] = phi i1 [ false, [[COND_TRUE49]] ], [ [[TMP6]], [[FLOW9]] ]
-; CHECK-NEXT:    [[TMP26:%.*]] = phi i1 [ false, [[COND_TRUE49]] ], [ [[TMP7]], [[FLOW9]] ]
-; CHECK-NEXT:    [[TMP27:%.*]] = phi i1 [ [[PRED4:%.*]], [[COND_TRUE49]] ], [ true, [[FLOW9]] ]
-; CHECK-NEXT:    br i1 [[TMP27]], label [[LOOP_EXIT_GUARD4:%.*]], label [[IRR_GUARD1]]
+; CHECK-NEXT:    br i1 [[TMP24:%.*]], label [[WHILE_END76:%.*]], label [[FLOW6]]
+; CHECK:       Flow10:
+; CHECK-NEXT:    [[TMP22]] = phi i1 [ [[PRED6:%.*]], [[WHILE_COND47]] ], [ undef, [[WHILE_BODY63]] ]
+; CHECK-NEXT:    [[TMP23]] = phi i1 [ false, [[WHILE_COND47]] ], [ true, [[WHILE_BODY63]] ]
+; CHECK-NEXT:    br label [[FLOW9]]
 ; CHECK:       Flow13:
-; CHECK-NEXT:    [[TMP28]] = phi i1 [ [[TMP8]], [[LOOP_EXIT_GUARD4]] ], [ undef, [[FLOW12]] ]
-; CHECK-NEXT:    [[TMP29:%.*]] = phi i1 [ [[TMP26]], [[LOOP_EXIT_GUARD4]] ], [ [[TMP15]], [[FLOW12]] ]
-; CHECK-NEXT:    [[TMP30:%.*]] = phi i1 [ [[TMP25]], [[LOOP_EXIT_GUARD4]] ], [ [[TMP16]], [[FLOW12]] ]
-; CHECK-NEXT:    [[TMP31]] = phi i1 [ [[TMP6]], [[LOOP_EXIT_GUARD4]] ], [ undef, [[FLOW12]] ]
-; CHECK-NEXT:    [[TMP32:%.*]] = phi i1 [ [[TMP24]], [[LOOP_EXIT_GUARD4]] ], [ true, [[FLOW12]] ]
-; CHECK-NEXT:    [[DOTINV14]] = xor i1 [[TMP29]], true
-; CHECK-NEXT:    [[DOTINV]] = xor i1 [[TMP30]], true
-; CHECK-NEXT:    br i1 [[TMP32]], label [[LOOP_EXIT_GUARD2]], label [[IRR_GUARD]]
-; CHECK:       loop.exit.guard4:
-; CHECK-NEXT:    br label [[FLOW13]]
+; CHECK-NEXT:    [[TMP24]] = phi i1 [ [[TMP15]], [[FLOW14]] ], [ [[TMP17]], [[FLOW12]] ]
+; CHECK-NEXT:    [[TMP25:%.*]] = phi i1 [ [[TMP16]], [[FLOW14]] ], [ true, [[FLOW12]] ]
+; CHECK-NEXT:    br i1 [[TMP25]], label [[LOOP_EXIT_GUARD:%.*]], label [[WHILE_COND]]
+; CHECK:       loop.exit.guard1:
+; CHECK-NEXT:    br i1 [[DOTINV]], label [[LOOP_EXIT_GUARD2]], label [[FLOW14]]
+; CHECK:       loop.exit.guard2:
+; CHECK-NEXT:    br i1 [[DOTINV11]], label [[IF_THEN69]], label [[FLOW15]]
 ;
 entry:
   br i1 %Pred0, label %if.end, label %if.then


        


More information about the llvm-branch-commits mailing list