From: Connor Abbott Date: Mon, 9 Dec 2019 11:04:00 +0000 (+0100) Subject: AMDGPU: Fix AMDGPUUnifyDivergentExitNodes with no normal returns X-Git-Tag: llvmorg-12-init~16335 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ce06d50756e9f59db50378753a42d03b9c3369c4;p=platform%2Fupstream%2Fllvm.git AMDGPU: Fix AMDGPUUnifyDivergentExitNodes with no normal returns Summary: The code was assuming in a few places that if there was only one exit from the function that it was a normal return, which is invalid. It could be an infinite loop, in which case we still need to insert the usual fake edge so that the null export happens. This fixes shaders that end with an infinite loop that discards. Reviewers: arsenm, nhaehnle, critson Subscribers: kzhuravl, jvesely, wdng, yaxunl, dstuttard, tpr, t-tye, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D71192 --- diff --git a/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp b/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp index 01bb60f..2569589 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUUnifyDivergentExitNodes.cpp @@ -195,7 +195,12 @@ static BasicBlock *unifyReturnBlockSet(Function &F, bool AMDGPUUnifyDivergentExitNodes::runOnFunction(Function &F) { auto &PDT = getAnalysis().getPostDomTree(); - if (PDT.getRoots().size() <= 1) + + // If there's only one exit, we don't need to do anything, unless this is a + // pixel shader and that exit is an infinite loop, since we still have to + // insert an export in that case. + if (PDT.getRoots().size() <= 1 && + F.getCallingConv() != CallingConv::AMDGPU_PS) return false; LegacyDivergenceAnalysis &DA = getAnalysis(); @@ -321,7 +326,7 @@ bool AMDGPUUnifyDivergentExitNodes::runOnFunction(Function &F) { if (ReturningBlocks.empty()) return false; // No blocks return - if (ReturningBlocks.size() == 1) + if (ReturningBlocks.size() == 1 && !InsertExport) return false; // Already has a single return block const TargetTransformInfo &TTI diff --git a/llvm/test/CodeGen/AMDGPU/kill-infinite-loop.ll b/llvm/test/CodeGen/AMDGPU/kill-infinite-loop.ll index 30280b9..a2358f3 100644 --- a/llvm/test/CodeGen/AMDGPU/kill-infinite-loop.ll +++ b/llvm/test/CodeGen/AMDGPU/kill-infinite-loop.ll @@ -45,6 +45,22 @@ end: ret void } +; test the case where there's only a kill in an infinite loop +; CHECK-LABEL: only_kill +; CHECK: exp null off, off, off, off done vm +; CHECK-NEXT: s_endpgm +; SIInsertSkips inserts an extra null export here, but it should be harmless. +; CHECK: exp null off, off, off, off done vm +; CHECK-NEXT: s_endpgm +define amdgpu_ps void @only_kill() #0 { +main_body: + br label %loop + +loop: + call void @llvm.amdgcn.kill(i1 false) #3 + br label %loop +} + ; In case there's an epilog, we shouldn't have to do this. ; CHECK-LABEL: return_nonvoid ; CHECK-NOT: exp null off, off, off, off done vm diff --git a/llvm/test/CodeGen/AMDGPU/update-phi.ll b/llvm/test/CodeGen/AMDGPU/update-phi.ll index 0577542..a40ccd6 100644 --- a/llvm/test/CodeGen/AMDGPU/update-phi.ll +++ b/llvm/test/CodeGen/AMDGPU/update-phi.ll @@ -14,12 +14,13 @@ define amdgpu_ps void @_amdgpu_ps_main() local_unnamed_addr #3 { ; IR-NEXT: [[DOT01:%.*]] = phi float [ 0.000000e+00, [[DOTLOOPEXIT]] ], [ [[N29:%.*]], [[TRANSITIONBLOCK:%.*]] ] ; IR-NEXT: [[N29]] = fadd float [[DOT01]], 1.000000e+00 ; IR-NEXT: [[N30:%.*]] = fcmp ogt float [[N29]], 4.000000e+00 -; IR-NEXT: br i1 true, label [[TRANSITIONBLOCK]], label [[DUMMYRETURNBLOCK:%.*]] +; IR-NEXT: br i1 true, label [[TRANSITIONBLOCK]], label [[UNIFIEDRETURNBLOCK:%.*]] ; IR: TransitionBlock: ; IR-NEXT: br i1 [[N30]], label [[DOTLOOPEXIT]], label [[N28]] ; IR: n31: ; IR-NEXT: ret void -; IR: DummyReturnBlock: +; IR: UnifiedReturnBlock: +; IR-NEXT: call void @llvm.amdgcn.exp.f32(i32 9, i32 0, float undef, float undef, float undef, float undef, i1 true, i1 true) ; IR-NEXT: ret void ; .entry: