From 65e868156f6b3d4e88147cb43a7e44ad8d2f1ad3 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Wed, 29 Apr 2015 00:59:51 +0000 Subject: [PATCH] Merging r234891: ------------------------------------------------------------------------ r234891 | thomas.stellard | 2015-04-14 10:36:45 -0400 (Tue, 14 Apr 2015) | 12 lines R600/SI: Fix verifier error caused by SIAnnotateControlFlow This pass will always try to insert llvm.SI.ifbreak intrinsics in the same block that its conditional value is computed in. This is a problem when conditions for breaks or continue are computed outside of the loop, because the llvm.SI.ifbreak intrinsic ends up being inserted outside of the loop. This patch fixes this problem by inserting the llvm.SI.ifbreak intrinsics in the loop header when the condition is computed outside the loop. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_36@236072 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/R600/SIAnnotateControlFlow.cpp | 19 +++++++++++------ test/CodeGen/R600/si-annotate-cf.ll | 25 +++++++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 test/CodeGen/R600/si-annotate-cf.ll diff --git a/lib/Target/R600/SIAnnotateControlFlow.cpp b/lib/Target/R600/SIAnnotateControlFlow.cpp index c99219dd907..f23cdb633b6 100644 --- a/lib/Target/R600/SIAnnotateControlFlow.cpp +++ b/lib/Target/R600/SIAnnotateControlFlow.cpp @@ -83,7 +83,7 @@ class SIAnnotateControlFlow : public FunctionPass { void insertElse(BranchInst *Term); - Value *handleLoopCondition(Value *Cond, PHINode *Broken); + Value *handleLoopCondition(Value *Cond, PHINode *Broken, llvm::Loop *L); void handleLoop(BranchInst *Term); @@ -207,7 +207,8 @@ void SIAnnotateControlFlow::insertElse(BranchInst *Term) { } /// \brief Recursively handle the condition leading to a loop -Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken) { +Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken, + llvm::Loop *L) { if (PHINode *Phi = dyn_cast(Cond)) { BasicBlock *Parent = Phi->getParent(); PHINode *NewPhi = PHINode::Create(Int64, 0, "", &Parent->front()); @@ -223,7 +224,7 @@ Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken) } Phi->setIncomingValue(i, BoolFalse); - Value *PhiArg = handleLoopCondition(Incoming, Broken); + Value *PhiArg = handleLoopCondition(Incoming, Broken, L); NewPhi->addIncoming(PhiArg, From); } @@ -253,7 +254,12 @@ Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken) } else if (Instruction *Inst = dyn_cast(Cond)) { BasicBlock *Parent = Inst->getParent(); - TerminatorInst *Insert = Parent->getTerminator(); + Instruction *Insert; + if (L->contains(Inst)) { + Insert = Parent->getTerminator(); + } else { + Insert = L->getHeader()->getFirstNonPHIOrDbgOrLifetime(); + } Value *Args[] = { Cond, Broken }; return CallInst::Create(IfBreak, Args, "", Insert); @@ -265,14 +271,15 @@ Value *SIAnnotateControlFlow::handleLoopCondition(Value *Cond, PHINode *Broken) /// \brief Handle a back edge (loop) void SIAnnotateControlFlow::handleLoop(BranchInst *Term) { + BasicBlock *BB = Term->getParent(); + llvm::Loop *L = LI->getLoopFor(BB); BasicBlock *Target = Term->getSuccessor(1); PHINode *Broken = PHINode::Create(Int64, 0, "", &Target->front()); Value *Cond = Term->getCondition(); Term->setCondition(BoolTrue); - Value *Arg = handleLoopCondition(Cond, Broken); + Value *Arg = handleLoopCondition(Cond, Broken, L); - BasicBlock *BB = Term->getParent(); for (pred_iterator PI = pred_begin(Target), PE = pred_end(Target); PI != PE; ++PI) { diff --git a/test/CodeGen/R600/si-annotate-cf.ll b/test/CodeGen/R600/si-annotate-cf.ll new file mode 100644 index 00000000000..3f3098862ef --- /dev/null +++ b/test/CodeGen/R600/si-annotate-cf.ll @@ -0,0 +1,25 @@ +; RUN: llc < %s -march=amdgcn -mcpu=verde -verify-machineinstrs | FileCheck --check-prefix=SI --check-prefix=FUNC %s +; RUN: llc < %s -march=amdgcn -mcpu=tonga -verify-machineinstrs | FileCheck --check-prefix=SI --check-prefix=FUNC %s + +; FUNC-LABEL: {{^}}break_inserted_outside_of_loop: + +; SI: [[LOOP_LABEL:[A-Z0-9]+]]: +; Lowered break instructin: +; SI: s_or_b64 +; Lowered Loop instruction: +; SI: s_andn2_b64 +; s_cbranch_execnz [[LOOP_LABEL]] +; SI: s_endpgm +define void @break_inserted_outside_of_loop(i32 addrspace(1)* %out, i32 %a, i32 %b) { +main_body: + %0 = and i32 %a, %b + %1 = trunc i32 %0 to i1 + br label %ENDIF + +ENDLOOP: + store i32 0, i32 addrspace(1)* %out + ret void + +ENDIF: + br i1 %1, label %ENDLOOP, label %ENDIF +}