[llvm] 4d08156 - [Uniformity] fix assert in a cycle made divergent by outside branch

Sameer Sahasrabuddhe via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 18 00:55:41 PDT 2023


Author: Sameer Sahasrabuddhe
Date: 2023-08-18T13:25:13+05:30
New Revision: 4d081560cd3b6ac114aee15f50480dd978b55a44

URL: https://github.com/llvm/llvm-project/commit/4d081560cd3b6ac114aee15f50480dd978b55a44
DIFF: https://github.com/llvm/llvm-project/commit/4d081560cd3b6ac114aee15f50480dd978b55a44.diff

LOG: [Uniformity] fix assert in a cycle made divergent by outside branch

When diverged paths reach an irreducible cycle C, every block inside C gets
marked as a join block. Such a join block J may be contained in a nest of
reducible cycles inside C. When visiting J, we can only expect that the
outermost C is irreducible, which we now correctly assert.

Added: 
    

Modified: 
    llvm/include/llvm/ADT/GenericUniformityImpl.h
    llvm/test/Analysis/UniformityAnalysis/AMDGPU/irreducible/branch-outside.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/GenericUniformityImpl.h b/llvm/include/llvm/ADT/GenericUniformityImpl.h
index 954af5e44b894c..ddd0746ccd9163 100644
--- a/llvm/include/llvm/ADT/GenericUniformityImpl.h
+++ b/llvm/include/llvm/ADT/GenericUniformityImpl.h
@@ -946,16 +946,19 @@ static const CycleT *getExtDivCycle(const CycleT *Cycle,
   if (Cycle->contains(DivTermBlock))
     return nullptr;
 
+  const auto *OriginalCycle = Cycle;
   const auto *Parent = Cycle->getParentCycle();
   while (Parent && !Parent->contains(DivTermBlock)) {
-    // If the join is inside a child, then the parent must be
-    // irreducible. The only join in a reducible cyle is its own
-    // header.
-    assert(!Parent->isReducible());
     Cycle = Parent;
     Parent = Cycle->getParentCycle();
   }
 
+  // If the original cycle is not the outermost cycle, then the outermost cycle
+  // is irreducible. If the outermost cycle were reducible, then external
+  // diverged paths would not reach the original inner cycle.
+  (void)OriginalCycle;
+  assert(Cycle == OriginalCycle || !Cycle->isReducible());
+
   if (Cycle->isReducible()) {
     assert(Cycle->getHeader() == JoinBlock);
     return nullptr;
@@ -976,7 +979,7 @@ getIntDivCycle(const CycleT *Cycle, const BlockT *DivTermBlock,
                const BlockT *JoinBlock, const DominatorTreeT &DT,
                ContextT &Context) {
   LLVM_DEBUG(dbgs() << "examine join " << Context.print(JoinBlock)
-                    << "for internal branch " << Context.print(DivTermBlock)
+                    << " for internal branch " << Context.print(DivTermBlock)
                     << "\n");
   if (DT.properlyDominates(DivTermBlock, JoinBlock))
     return nullptr;

diff  --git a/llvm/test/Analysis/UniformityAnalysis/AMDGPU/irreducible/branch-outside.ll b/llvm/test/Analysis/UniformityAnalysis/AMDGPU/irreducible/branch-outside.ll
index 0227f7c8d762db..7fd8ac40e4bec8 100644
--- a/llvm/test/Analysis/UniformityAnalysis/AMDGPU/irreducible/branch-outside.ll
+++ b/llvm/test/Analysis/UniformityAnalysis/AMDGPU/irreducible/branch-outside.ll
@@ -78,4 +78,42 @@ exit:
   ret void
 }
 
+; Just make sure that this does not asert. It is important that Q is recognized
+; as the header of the outermost cycle. The incorrect assert was exercised by
+; this hierarchy:
+;
+; CycleInfo for function: irreducible_outer_cycle
+;    depth=1: entries(Q R) C B D
+;        depth=2: entries(R) C B D
+;            depth=3: entries(B) D
+;
+; CHECK-LABEL: UniformityInfo for function 'irreducible_outer_cycle':
+; CHECK: CYCLES ASSSUMED DIVERGENT:
+; CHECK:  depth=1: entries(Q R) C B D
+define void @irreducible_outer_cycle(i1 %c1, i1 %c2, i1 %c3) {
+entry:
+  br i1 %c1, label %P, label %Q
+
+P:
+  br i1 false, label %Q, label %R
+
+Q:
+  br label %R
+
+R:
+  br i1 false, label %Q, label %B
+
+B:
+  br i1 false, label %C, label %D
+
+D:
+  br label %B
+
+C:
+  br i1 false, label %R, label %exit
+
+exit:
+  ret void
+}
+
 declare i32 @llvm.amdgcn.workitem.id.x() #0


        


More information about the llvm-commits mailing list