[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