mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
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. llvm-svn: 234891
This commit is contained in:
parent
bf27a58630
commit
f21854a72d
@ -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<PHINode>(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<Instruction>(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) {
|
||||
|
||||
|
25
test/CodeGen/R600/si-annotate-cf.ll
Normal file
25
test/CodeGen/R600/si-annotate-cf.ll
Normal file
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user