@@ -614,6 +614,22 @@ template <typename ContextT> class DivergencePropagator {
614614
615615    //  Bootstrap with branch targets
616616    auto  const  *DivTermCycle = CI.getCycle (&DivTermBlock);
617+ 
618+     //  Locate the largest ancestor cycle that is not reducible and does not
619+     //  contain a reducible ancestor. This is done with a lambda that is defined
620+     //  and invoked in the same statement.
621+     const  CycleT *IrreducibleAncestor = [](const  CycleT *C) -> const  CycleT* {
622+       if  (!C) return  nullptr ;
623+       if  (C->isReducible ()) return  nullptr ;
624+       while  (const  CycleT *P = C->getParentCycle ()) {
625+         if  (P->isReducible ()) return  C;
626+         C = P;
627+       }
628+       assert (!C->getParentCycle ());
629+       assert (!C->isReducible ());
630+       return  C;
631+     } (DivTermCycle);
632+ 
617633    for  (const  auto  *SuccBlock : successors (&DivTermBlock)) {
618634      if  (DivTermCycle && !DivTermCycle->contains (SuccBlock)) {
619635        //  If DivTerm exits the cycle immediately, computeJoin() might
@@ -626,19 +642,6 @@ template <typename ContextT> class DivergencePropagator {
626642      visitEdge (*SuccBlock, *SuccBlock);
627643    }
628644
629-     //  Return true if B is inside an irreducible cycle
630-     auto  IsInIrreducibleCycle = [this ](const  BlockT *B) {
631-       for  (const  auto  *Cycle = CI.getCycle (B); Cycle;
632-            Cycle = Cycle->getParentCycle ()) {
633-         //  If everything is inside a reducible cycle, then look no further
634-         if  (Cycle->isReducible () && Cycle->contains (&DivTermBlock))
635-           return  false ;
636-         if  (!Cycle->isReducible ())
637-           return  true ;
638-       }
639-       return  false ;
640-     };
641- 
642645    //  Technically propagation can continue until it reaches the last node.
643646    // 
644647    //  For efficiency, propagation can stop if FreshLabels.count()==1. But
@@ -652,7 +655,7 @@ template <typename ContextT> class DivergencePropagator {
652655      const  auto  *Block = CyclePOT[BlockIdx];
653656      //  If no irreducible cycle, stop if freshLable.count() = 1 and Block
654657      //  is the IPD. If it is in any irreducible cycle, continue propagation.
655-       if  (FreshLabels.count () == 1  && ! IsInIrreducibleCycle (Block))
658+       if  (FreshLabels.count () == 1  && (!IrreducibleAncestor || !IrreducibleAncestor-> contains (Block) ))
656659        break ;
657660
658661      LLVM_DEBUG (dbgs () << " Current labels:\n "  ; printDefs (dbgs ()));
0 commit comments