For a loop, a join block is a block that is reachable along multiple
disjoint paths from the exiting block of a loop. If the exit condition
of the loop is divergent, then such join blocks must also be marked
divergent. This currently fails in some cases because not all join
blocks are identified correctly.
The workaround is to conservatively mark every join block of any
branch (not necessarily the exiting block of a loop) as divergent.
Add a FIXME here that clearly states that this is a quickfix. You could also add the following test (in comments since it will fail) to your test case to document the imprecision caused by this:
; CHECK: bb2: ; CHECK-NOT: DIVERGENT: %Guard.bb2 = phi i1 [ true, %bb1 ], [ false, %bb0 ] define protected amdgpu_kernel void @test2(i1 %uni) { bb0: %tid.x = call i32 @llvm.amdgcn.workitem.id.x() %i5 = icmp eq i32 %tid.x, -1 br i1 %uni, label %bb1, label %bb2 bb1: ; preds = %bb2, %bb0 %lsr.iv = phi i32 [ 7, %bb0 ], [ %lsr.iv.next, %bb1 ] %lsr.iv.next = add nsw i32 %lsr.iv, -1 br i1 %i5, label %bb2, label %bb1 bb2: ; preds = %bb2, %bb1 %Guard.bb2 = phi i1 [ true, %bb1 ], [ false, %bb0 ] ret void } attributes #0 = { nounwind readnone speculatable }