diff options
-rw-r--r-- | llvm/lib/Target/R600/SIAnnotateControlFlow.cpp | 10 | ||||
-rw-r--r-- | llvm/test/CodeGen/R600/si-annotate-cf.ll | 38 |
2 files changed, 47 insertions, 1 deletions
diff --git a/llvm/lib/Target/R600/SIAnnotateControlFlow.cpp b/llvm/lib/Target/R600/SIAnnotateControlFlow.cpp index f23cdb6..b8165fb 100644 --- a/llvm/lib/Target/R600/SIAnnotateControlFlow.cpp +++ b/llvm/lib/Target/R600/SIAnnotateControlFlow.cpp @@ -209,7 +209,15 @@ void SIAnnotateControlFlow::insertElse(BranchInst *Term) { /// \brief Recursively handle the condition leading to a loop Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken, llvm::Loop *L) { - if (PHINode *Phi = dyn_cast<PHINode>(Cond)) { + + // Only search through PHI nodes which are inside the loop. If we try this + // with PHI nodes that are outside of the loop, we end up inserting new PHI + // nodes outside of the loop which depend on values defined inside the loop. + // This will break the module with + // 'Instruction does not dominate all users!' errors. + PHINode *Phi = nullptr; + if ((Phi = dyn_cast<PHINode>(Cond)) && L->contains(Phi)) { + BasicBlock *Parent = Phi->getParent(); PHINode *NewPhi = PHINode::Create(Int64, 0, "", &Parent->front()); Value *Ret = NewPhi; diff --git a/llvm/test/CodeGen/R600/si-annotate-cf.ll b/llvm/test/CodeGen/R600/si-annotate-cf.ll index 3f30988..1b49a82 100644 --- a/llvm/test/CodeGen/R600/si-annotate-cf.ll +++ b/llvm/test/CodeGen/R600/si-annotate-cf.ll @@ -23,3 +23,41 @@ ENDLOOP: ENDIF: br i1 %1, label %ENDLOOP, label %ENDIF } + + +; FUNC-LABEL: {{^}}phi_cond_outside_loop: +; FIXME: This could be folded into the s_or_b64 instruction +; SI: s_mov_b64 [[ZERO:s\[[0-9]+:[0-9]+\]]], 0 +; SI: [[LOOP_LABEL:[A-Z0-9]+]] +; SI: v_cmp_ne_i32_e64 [[COND:s\[[0-9]+:[0-9]+\]]], v{{[0-9]+}}, 0 + +; SI_IF_BREAK instruction: +; SI: s_or_b64 [[BREAK:s\[[0-9]+:[0-9]+\]]], [[COND]], [[ZERO]] + +; SI_LOOP instruction: +; SI: s_andn2_b64 exec, exec, [[BREAK]] +; SI: s_cbranch_execnz [[LOOP_LABEL]] +; SI: s_endpgm + +define void @phi_cond_outside_loop(i32 %a, i32 %b) { +entry: + %0 = icmp eq i32 %a , 0 + br i1 %0, label %if, label %else + +if: + br label %endif + +else: + %1 = icmp eq i32 %b, 0 + br label %endif + +endif: + %2 = phi i1 [0, %if], [%1, %else] + br label %loop + +loop: + br i1 %2, label %exit, label %loop + +exit: + ret void +} |