<div dir="auto"><div>Hi Mikael,<div dir="auto"><br></div><div dir="auto">I'm on vacation till Wednesday and will investigate on Thursday. If that's serious enough, feel free to revert.</div><br><div class="gmail_extra"><br><div class="gmail_quote">On Jul 4, 2017 00:37, "Mikael Holmén" <<a href="mailto:mikael.holmen@ericsson.com">mikael.holmen@ericsson.com</a>> wrote:<br type="attribution"><blockquote class="quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Jakub,<br>
<br>
I get a crash when running -loop-rotate on the attached program with your patch:<br>
<br>
opt -S -loop-rotate -o - reduced9.ll<br>
<br>
gives<br>
<br>
opt: ../include/llvm/Support/Generi<wbr>cDomTree.h:499: void llvm::DominatorTreeBase<llvm::<wbr>BasicBlock>::changeImmediateDo<wbr>minator(DomTreeNodeBase<NodeT> *, DomTreeNodeBase<NodeT> *) [N = llvm::BasicBlock]: Assertion `N && NewIDom && "Cannot change null node pointers!"' failed.<br>
<br>
<br>
-debug printouts:<br>
<br>
LoopSimplify: Resolving "br i1 undef" to exit in bb2<br>
LoopSimplify: Creating dedicated exit block bb6.loopexit<br>
LoopRotation: rotating Loop at depth 1 containing: %bb1<header><exiting>,%bb2<exi<wbr>ting>,%bb4<latch><br>
<br>
Regards,<br>
Mikael<div class="elided-text"><br>
<br>
On 07/01/2017 02:23 AM, Jakub Kuderski via llvm-commits wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: kuhar<br>
Date: Fri Jun 30 17:23:01 2017<br>
New Revision: 306919<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=306919&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=306919&view=rev</a><br>
Log:<br>
[Dominators] Reapply r306892, r306893, r306893.<br>
<br>
This reverts commit r306907 and reapplies the patches in the title.<br>
The patches used to make one of the<br>
CodeGen/ARM/2011-02-07-Antidep<wbr>Clobber.ll test to fail because of a<br>
missing null check.<br>
<br>
Modified:<br>
     llvm/trunk/include/llvm/Analy<wbr>sis/IteratedDominanceFrontier.<wbr>h<br>
     llvm/trunk/include/llvm/Suppo<wbr>rt/GenericDomTree.h<br>
     llvm/trunk/include/llvm/Suppo<wbr>rt/GenericDomTreeConstruction.<wbr>h<br>
     llvm/trunk/lib/Analysis/Itera<wbr>tedDominanceFrontier.cpp<br>
     llvm/trunk/unittests/IR/Domin<wbr>atorTreeTest.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/Analys<wbr>is/IteratedDominanceFrontier.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/IteratedDominanceFrontier.h?rev=306919&r1=306918&r2=306919&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/include/llvm/<wbr>Analysis/IteratedDominanceFron<wbr>tier.h?rev=306919&r1=306918&<wbr>r2=306919&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/Analys<wbr>is/IteratedDominanceFrontier.h (original)<br>
+++ llvm/trunk/include/llvm/Analys<wbr>is/IteratedDominanceFrontier.h Fri Jun 30 17:23:01 2017<br>
@@ -86,7 +86,6 @@ public:<br>
  private:<br>
    DominatorTreeBase<BasicBlock> &DT;<br>
    bool useLiveIn;<br>
-  DenseMap<DomTreeNode *, unsigned> DomLevels;<br>
    const SmallPtrSetImpl<BasicBlock *> *LiveInBlocks;<br>
    const SmallPtrSetImpl<BasicBlock *> *DefBlocks;<br>
  };<br>
<br>
Modified: llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTree.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/GenericDomTree.h?rev=306919&r1=306918&r2=306919&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/include/llvm/<wbr>Support/GenericDomTree.h?rev=<wbr>306919&r1=306918&r2=306919&<wbr>view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTree.h (original)<br>
+++ llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTree.h Fri Jun 30 17:23:01 2017<br>
@@ -65,12 +65,14 @@ template <class NodeT> class DomTreeNode<br>
      NodeT *TheBB;<br>
    DomTreeNodeBase *IDom;<br>
+  unsigned Level;<br>
    std::vector<DomTreeNodeBase *> Children;<br>
    mutable unsigned DFSNumIn = ~0;<br>
    mutable unsigned DFSNumOut = ~0;<br>
     public:<br>
-  DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom) : TheBB(BB), IDom(iDom) {}<br>
+  DomTreeNodeBase(NodeT *BB, DomTreeNodeBase *iDom)<br>
+      : TheBB(BB), IDom(iDom), Level(IDom ? IDom->Level + 1 : 0) {}<br>
      using iterator = typename std::vector<DomTreeNodeBase *>::iterator;<br>
    using const_iterator =<br>
@@ -83,6 +85,7 @@ template <class NodeT> class DomTreeNode<br>
      NodeT *getBlock() const { return TheBB; }<br>
    DomTreeNodeBase *getIDom() const { return IDom; }<br>
+  unsigned getLevel() const { return Level; }<br>
      const std::vector<DomTreeNodeBase *> &getChildren() const { return Children; }<br>
  @@ -100,6 +103,8 @@ template <class NodeT> class DomTreeNode<br>
      if (getNumChildren() != Other->getNumChildren())<br>
        return true;<br>
  +    if (Level != Other->Level) return true;<br>
+<br>
      SmallPtrSet<const NodeT *, 4> OtherChildren;<br>
      for (const DomTreeNodeBase *I : *Other) {<br>
        const NodeT *Nd = I->getBlock();<br>
@@ -116,18 +121,19 @@ template <class NodeT> class DomTreeNode<br>
      void setIDom(DomTreeNodeBase *NewIDom) {<br>
      assert(IDom && "No immediate dominator?");<br>
-    if (IDom != NewIDom) {<br>
-      typename std::vector<DomTreeNodeBase *>::iterator I =<br>
-          find(IDom->Children, this);<br>
-      assert(I != IDom->Children.end() &&<br>
-             "Not in immediate dominator children set!");<br>
-      // I am no longer your child...<br>
-      IDom->Children.erase(I);<br>
-<br>
-      // Switch to new dominator<br>
-      IDom = NewIDom;<br>
-      IDom->Children.push_back(this)<wbr>;<br>
-    }<br>
+    if (IDom == NewIDom) return;<br>
+<br>
+    auto I = find(IDom->Children, this);<br>
+    assert(I != IDom->Children.end() &&<br>
+           "Not in immediate dominator children set!");<br>
+    // I am no longer your child...<br>
+    IDom->Children.erase(I);<br>
+<br>
+    // Switch to new dominator<br>
+    IDom = NewIDom;<br>
+    IDom->Children.push_back(this)<wbr>;<br>
+<br>
+    UpdateLevel();<br>
    }<br>
      /// getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes<br>
@@ -143,6 +149,23 @@ private:<br>
      return this->DFSNumIn >= other->DFSNumIn &&<br>
             this->DFSNumOut <= other->DFSNumOut;<br>
    }<br>
+<br>
+  void UpdateLevel() {<br>
+    assert(IDom);<br>
+    if (Level == IDom->Level + 1) return;<br>
+<br>
+    SmallVector<DomTreeNodeBase *, 64> WorkStack = {this};<br>
+<br>
+    while (!WorkStack.empty()) {<br>
+      DomTreeNodeBase *Current = WorkStack.pop_back_val();<br>
+      Current->Level = Current->IDom->Level + 1;<br>
+<br>
+      for (DomTreeNodeBase *C : *Current) {<br>
+        assert(C->IDom);<br>
+        if (C->Level != C->IDom->Level + 1) WorkStack.push_back(C);<br>
+      }<br>
+    }<br>
+  }<br>
  };<br>
    template <class NodeT><br>
@@ -152,9 +175,10 @@ raw_ostream &operator<<(raw_ostream &O,<br>
    else<br>
      O << " <<exit node>>";<br>
  -  O << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "}";<br>
+  O << " {" << Node->getDFSNumIn() << "," << Node->getDFSNumOut() << "} ["<br>
+    << Node->getLevel() << "]\n";<br>
  -  return O << "\n";<br>
+  return O;<br>
  }<br>
    template <class NodeT><br>
@@ -345,6 +369,13 @@ template <class NodeT> class DominatorTr<br>
      if (!isReachableFromEntry(A))<br>
        return false;<br>
  +    if (B->getIDom() == A) return true;<br>
+<br>
+    if (A->getIDom() == B) return false;<br>
+<br>
+    // A can only dominate B if it is higher in the tree.<br>
+    if (A->getLevel() >= B->getLevel()) return false;<br>
+<br>
      // Compare the result of the tree walk and the dfs numbers, if expensive<br>
      // checks are enabled.<br>
  #ifdef EXPENSIVE_CHECKS<br>
@@ -376,7 +407,7 @@ template <class NodeT> class DominatorTr<br>
      /// findNearestCommonDominator - Find nearest common dominator basic block<br>
    /// for basic block A and B. If there is no such block then return NULL.<br>
-  NodeT *findNearestCommonDominator(No<wbr>deT *A, NodeT *B) {<br>
+  NodeT *findNearestCommonDominator(No<wbr>deT *A, NodeT *B) const {<br>
      assert(A->getParent() == B->getParent() &&<br>
             "Two blocks are not in same function");<br>
  @@ -388,54 +419,24 @@ template <class NodeT> class DominatorTr<br>
          return &Entry;<br>
      }<br>
  -    // If B dominates A then B is nearest common dominator.<br>
-    if (dominates(B, A))<br>
-      return B;<br>
-<br>
-    // If A dominates B then A is nearest common dominator.<br>
-    if (dominates(A, B))<br>
-      return A;<br>
-<br>
      DomTreeNodeBase<NodeT> *NodeA = getNode(A);<br>
      DomTreeNodeBase<NodeT> *NodeB = getNode(B);<br>
  -    // If we have DFS info, then we can avoid all allocations by just querying<br>
-    // it from each IDom. Note that because we call 'dominates' twice above, we<br>
-    // expect to call through this code at most 16 times in a row without<br>
-    // building valid DFS information. This is important as below is a *very*<br>
-    // slow tree walk.<br>
-    if (DFSInfoValid) {<br>
-      DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();<br>
-      while (IDomA) {<br>
-        if (NodeB->DominatedBy(IDomA))<br>
-          return IDomA->getBlock();<br>
-        IDomA = IDomA->getIDom();<br>
-      }<br>
-      return nullptr;<br>
-    }<br>
-<br>
-    // Collect NodeA dominators set.<br>
-    SmallPtrSet<DomTreeNodeBase<No<wbr>deT> *, 16> NodeADoms;<br>
-    NodeADoms.insert(NodeA);<br>
-    DomTreeNodeBase<NodeT> *IDomA = NodeA->getIDom();<br>
-    while (IDomA) {<br>
-      NodeADoms.insert(IDomA);<br>
-      IDomA = IDomA->getIDom();<br>
-    }<br>
+    if (!NodeA || !NodeB) return nullptr;<br>
  -    // Walk NodeB immediate dominators chain and find common dominator node.<br>
-    DomTreeNodeBase<NodeT> *IDomB = NodeB->getIDom();<br>
-    while (IDomB) {<br>
-      if (NodeADoms.count(IDomB) != 0)<br>
-        return IDomB->getBlock();<br>
+    // Use level information to go up the tree until the levels match. Then<br>
+    // continue going up til we arrive at the same node.<br>
+    while (NodeA && NodeA != NodeB) {<br>
+      if (NodeA->getLevel() < NodeB->getLevel()) std::swap(NodeA, NodeB);<br>
  -      IDomB = IDomB->getIDom();<br>
+      NodeA = NodeA->IDom;<br>
      }<br>
  -    return nullptr;<br>
+    return NodeA ? NodeA->getBlock() : nullptr;<br>
    }<br>
  -  const NodeT *findNearestCommonDominator(co<wbr>nst NodeT *A, const NodeT *B) {<br>
+  const NodeT *findNearestCommonDominator(co<wbr>nst NodeT *A,<br>
+                                          const NodeT *B) const {<br>
      // Cast away the const qualifiers here. This is ok since<br>
      // const is re-introduced on the return type.<br>
      return findNearestCommonDominator(con<wbr>st_cast<NodeT *>(A),<br>
@@ -481,8 +482,10 @@ template <class NodeT> class DominatorTr<br>
      } else {<br>
        assert(Roots.size() == 1);<br>
        NodeT *OldRoot = Roots.front();<br>
-      DomTreeNodes[OldRoot] =<br>
-        NewNode->addChild(std::move(Do<wbr>mTreeNodes[OldRoot]));<br>
+      auto &OldNode = DomTreeNodes[OldRoot];<br>
+      OldNode = NewNode->addChild(std::move(Do<wbr>mTreeNodes[OldRoot]));<br>
+      OldNode->IDom = NewNode;<br>
+      OldNode->UpdateLevel();<br>
        Roots[0] = BB;<br>
      }<br>
      return RootNode = NewNode;<br>
<br>
Modified: llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTreeConstruction.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/GenericDomTreeConstruction.h?rev=306919&r1=306918&r2=306919&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/include/llvm/<wbr>Support/GenericDomTreeConstruc<wbr>tion.h?rev=306919&r1=306918&<wbr>r2=306919&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTreeConstruction.h (original)<br>
+++ llvm/trunk/include/llvm/Suppor<wbr>t/GenericDomTreeConstruction.h Fri Jun 30 17:23:01 2017<br>
@@ -280,6 +280,7 @@ struct SemiNCAInfo {<br>
    }<br>
      void doFullDFSWalk(const DomTreeT &DT) {<br>
+    NumToNode.push_back(nullptr);<br>
      unsigned Num = 0;<br>
      for (auto *Root : DT.Roots)<br>
        if (!DT.isPostDominator())<br>
@@ -317,6 +318,78 @@ struct SemiNCAInfo {<br>
        return true;<br>
    }<br>
+<br>
+  // Check if for every parent with a level L in the tree all of its children<br>
+  // have level L + 1.<br>
+  static bool VerifyLevels(const DomTreeT &DT) {<br>
+    for (auto &NodeToTN : DT.DomTreeNodes) {<br>
+      const TreeNodePtr TN = NodeToTN.second.get();<br>
+      const NodePtr BB = TN->getBlock();<br>
+      if (!BB) continue;<br>
+<br>
+      const TreeNodePtr IDom = TN->getIDom();<br>
+      if (!IDom && TN->getLevel() != 0) {<br>
+        errs() << "Node without an IDom ";<br>
+        PrintBlockOrNullptr(errs(), BB);<br>
+        errs() << " has a nonzero level " << TN->getLevel() << "!\n";<br>
+        errs().flush();<br>
+<br>
+        return false;<br>
+      }<br>
+<br>
+      if (IDom && TN->getLevel() != IDom->getLevel() + 1) {<br>
+        errs() << "Node ";<br>
+        PrintBlockOrNullptr(errs(), BB);<br>
+        errs() << " has level " << TN->getLevel() << " while it's IDom ";<br>
+        PrintBlockOrNullptr(errs(), IDom->getBlock());<br>
+        errs() << " has level " << IDom->getLevel() << "!\n";<br>
+        errs().flush();<br>
+<br>
+        return false;<br>
+      }<br>
+    }<br>
+<br>
+    return true;<br>
+  }<br>
+<br>
+  // Checks if for every edge From -> To in the graph<br>
+  //     NCD(From, To) == IDom(To) or To.<br>
+  bool verifyNCD(const DomTreeT &DT) {<br>
+    clear();<br>
+    doFullDFSWalk(DT);<br>
+<br>
+    for (auto &BlockToInfo : NodeToInfo) {<br>
+      auto &Info = BlockToInfo.second;<br>
+<br>
+      const NodePtr From = NumToNode[Info.Parent];<br>
+      if (!From) continue;<br>
+<br>
+      const NodePtr To = BlockToInfo.first;<br>
+      const TreeNodePtr ToTN = DT.getNode(To);<br>
+      assert(ToTN);<br>
+<br>
+      const NodePtr NCD = DT.findNearestCommonDominator(<wbr>From, To);<br>
+      const TreeNodePtr NCDTN = NCD ? DT.getNode(NCD) : nullptr;<br>
+      const TreeNodePtr ToIDom = ToTN->getIDom();<br>
+      if (NCDTN != ToTN && NCDTN != ToIDom) {<br>
+        errs() << "NearestCommonDominator verification failed:\n\tNCD(From:";<br>
+        PrintBlockOrNullptr(errs(), From);<br>
+        errs() << ", To:";<br>
+        PrintBlockOrNullptr(errs(), To);<br>
+        errs() << ") = ";<br>
+        PrintBlockOrNullptr(errs(), NCD);<br>
+        errs() << ",\t (should be To or IDom[To]: ";<br>
+        PrintBlockOrNullptr(errs(), ToIDom ? ToIDom->getBlock() : nullptr);<br>
+        errs() << ")\n";<br>
+        errs().flush();<br>
+<br>
+        return false;<br>
+      }<br>
+    }<br>
+<br>
+    return true;<br>
+  }<br>
+<br>
    // The below routines verify the correctness of the dominator tree relative to<br>
    // the CFG it's coming from.  A tree is a dominator tree iff it has two<br>
    // properties, called the parent property and the sibling property.  Tarjan<br>
@@ -441,9 +514,9 @@ bool Verify(const DominatorTreeBaseByGra<br>
                  "NodePtr should be a pointer type");<br>
    SemiNCAInfo<typename std::remove_pointer<NodePtr>::<wbr>type> SNCA;<br>
  -  return SNCA.verifyReachability(DT) && SNCA.verifyParentProperty(DT) &&<br>
+  return SNCA.verifyReachability(DT) && SNCA.VerifyLevels(DT) &&<br>
+         SNCA.verifyNCD(DT) && SNCA.verifyParentProperty(DT) &&<br>
           SNCA.verifySiblingProperty(<wbr>DT);<br>
-<br>
  }<br>
    }  // namespace DomTreeBuilder<br>
<br>
Modified: llvm/trunk/lib/Analysis/Iterat<wbr>edDominanceFrontier.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/IteratedDominanceFrontier.cpp?rev=306919&r1=306918&r2=306919&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/Analysis/<wbr>IteratedDominanceFrontier.cpp?<wbr>rev=306919&r1=306918&r2=306919<wbr>&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/lib/Analysis/Iterat<wbr>edDominanceFrontier.cpp (original)<br>
+++ llvm/trunk/lib/Analysis/Iterat<wbr>edDominanceFrontier.cpp Fri Jun 30 17:23:01 2017<br>
@@ -20,14 +20,6 @@ namespace llvm {<br>
  template <class NodeTy><br>
  void IDFCalculator<NodeTy>::calcula<wbr>te(<br>
      SmallVectorImpl<BasicBlock *> &PHIBlocks) {<br>
-  // If we haven't computed dominator tree levels, do so now.<br>
-  if (DomLevels.empty()) {<br>
-    for (auto DFI = df_begin(DT.getRootNode()), DFE = df_end(DT.getRootNode());<br>
-         DFI != DFE; ++DFI) {<br>
-      DomLevels[*DFI] = DFI.getPathLength() - 1;<br>
-    }<br>
-  }<br>
-<br>
    // Use a priority queue keyed on dominator tree level so that inserted nodes<br>
    // are handled from the bottom of the dominator tree upwards.<br>
    typedef std::pair<DomTreeNode *, unsigned> DomTreeNodePair;<br>
@@ -37,7 +29,7 @@ void IDFCalculator<NodeTy>::calcula<wbr>te(<br>
      for (BasicBlock *BB : *DefBlocks) {<br>
      if (DomTreeNode *Node = DT.getNode(BB))<br>
-      PQ.push(std::make_pair(Node, DomLevels.lookup(Node)));<br>
+      PQ.push({Node, Node->getLevel()});<br>
    }<br>
      SmallVector<DomTreeNode *, 32> Worklist;<br>
@@ -72,7 +64,7 @@ void IDFCalculator<NodeTy>::calcula<wbr>te(<br>
          if (SuccNode->getIDom() == Node)<br>
            continue;<br>
  -        unsigned SuccLevel = DomLevels.lookup(SuccNode);<br>
+        const unsigned SuccLevel = SuccNode->getLevel();<br>
          if (SuccLevel > RootLevel)<br>
            continue;<br>
  <br>
Modified: llvm/trunk/unittests/IR/Domina<wbr>torTreeTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/DominatorTreeTest.cpp?rev=306919&r1=306918&r2=306919&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/unittests/IR/<wbr>DominatorTreeTest.cpp?rev=3069<wbr>19&r1=306918&r2=306919&view=<wbr>diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- llvm/trunk/unittests/IR/Domina<wbr>torTreeTest.cpp (original)<br>
+++ llvm/trunk/unittests/IR/Domina<wbr>torTreeTest.cpp Fri Jun 30 17:23:01 2017<br>
@@ -230,6 +230,12 @@ TEST(DominatorTree, Unreachable) {<br>
          EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tDFSNumIn(), 3UL);<br>
          EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tDFSNumOut(), 4UL);<br>
  +        // Check levels before<br>
+        EXPECT_EQ(DT->getNode(BB0)->ge<wbr>tLevel(), 0U);<br>
+        EXPECT_EQ(DT->getNode(BB1)->ge<wbr>tLevel(), 1U);<br>
+        EXPECT_EQ(DT->getNode(BB2)->ge<wbr>tLevel(), 1U);<br>
+        EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tLevel(), 1U);<br>
+<br>
          // Reattach block 3 to block 1 and recalculate<br>
          BB1->getTerminator()->eraseFro<wbr>mParent();<br>
          BranchInst::Create(BB4, BB3, ConstantInt::getTrue(F.getCont<wbr>ext()), BB1);<br>
@@ -248,6 +254,13 @@ TEST(DominatorTree, Unreachable) {<br>
          EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tDFSNumIn(), 5UL);<br>
          EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tDFSNumOut(), 6UL);<br>
  +        // Check levels after<br>
+        EXPECT_EQ(DT->getNode(BB0)->ge<wbr>tLevel(), 0U);<br>
+        EXPECT_EQ(DT->getNode(BB1)->ge<wbr>tLevel(), 1U);<br>
+        EXPECT_EQ(DT->getNode(BB2)->ge<wbr>tLevel(), 1U);<br>
+        EXPECT_EQ(DT->getNode(BB3)->ge<wbr>tLevel(), 2U);<br>
+        EXPECT_EQ(DT->getNode(BB4)->ge<wbr>tLevel(), 1U);<br>
+<br>
          // Change root node<br>
          DT->verifyDomTree();<br>
          BasicBlock *NewEntry =<br>
<br>
<br>
______________________________<wbr>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-commits</a><br>
<br>
</blockquote>
</div></blockquote></div><br></div></div></div>