Skip to content

Commit ba93685

Browse files
committed
[VPlan] Also use original parent loop for exit VPBBs.
When vectorizing loops with early exits that is nested within another one, one of the loop exits may be outside both loops, so setting adding it to the parent loop is incorrect. Also use the original parent loop for exit blocks.
1 parent ad6bb70 commit ba93685

File tree

2 files changed

+40
-7
lines changed

2 files changed

+40
-7
lines changed

llvm/lib/Transforms/Vectorize/VPlan.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -411,12 +411,16 @@ void VPBasicBlock::connectToPredecessors(VPTransformState &State) {
411411
// Register NewBB in its loop. In innermost loops its the same for all
412412
// BB's.
413413
Loop *ParentLoop = State.CurrentParentLoop;
414-
// If this block has a sole successor that is an exit block then it needs
415-
// adding to the same parent loop as the exit block.
416-
VPBlockBase *SuccVPBB = getSingleSuccessor();
417-
if (SuccVPBB && State.Plan->isExitBlock(SuccVPBB))
418-
ParentLoop =
419-
State.LI->getLoopFor(cast<VPIRBasicBlock>(SuccVPBB)->getIRBasicBlock());
414+
// If this block has a sole successor that is an exit block or is an exit
415+
// block itself then it needs adding to the same parent loop as the exit
416+
// block.
417+
VPBlockBase *SuccOrExitVPB = getSingleSuccessor();
418+
SuccOrExitVPB = SuccOrExitVPB ? SuccOrExitVPB : this;
419+
if (State.Plan->isExitBlock(SuccOrExitVPB)) {
420+
ParentLoop = State.LI->getLoopFor(
421+
cast<VPIRBasicBlock>(SuccOrExitVPB)->getIRBasicBlock());
422+
}
423+
420424
if (ParentLoop && !State.LI->getLoopFor(NewBB))
421425
ParentLoop->addBasicBlockToLoop(NewBB, *State.LI);
422426

llvm/test/Transforms/LoopVectorize/single_early_exit_with_outer_loop.ll

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -S < %s -p loop-vectorize,'print<loops>' -disable-output -enable-early-exit-vectorization 2>&1 | FileCheck %s
1+
; RUN: opt -S < %s -passes='loop-vectorize,verify<loops>,print<loops>' -disable-output -enable-early-exit-vectorization 2>&1 | FileCheck %s
22

33
declare void @init_mem(ptr, i64);
44

@@ -89,3 +89,32 @@ loop.outer.latch:
8989
%count.outer.next = add i64 %count.outer, %t
9090
br label %loop.outer
9191
}
92+
93+
define i32 @early_exit_branch_to_outer_header() {
94+
; CHECK-LABEL: Loop info for function 'early_exit_branch_to_outer_header':
95+
; CHECK-NEXT: Loop at depth 1 containing: %outer.header<header>,%loop.header,%loop.latch<exiting>,%outer.header.loopexit<latch>,%scalar.ph,%vector.ph,%vector.body,%middle.split,%middle.block<exiting>,%vector.early.exit
96+
; CHECK-NEXT: Loop at depth 2 containing: %loop.header<header><exiting>,%loop.latch<latch><exiting>
97+
; CHECK-NEXT: Loop at depth 2 containing: %vector.body<header><latch><exiting>
98+
entry:
99+
%src = alloca [1024 x i8]
100+
call void @init_mem(ptr %src, i64 1024)
101+
br label %outer.header
102+
103+
outer.header:
104+
br label %loop.header
105+
106+
loop.header:
107+
%iv = phi i64 [ 0, %outer.header ], [ %iv.next, %loop.latch ]
108+
%gep.src = getelementptr i8, ptr %src, i64 %iv
109+
%l = load i8, ptr %gep.src, align 1
110+
%c = icmp eq i8 %l, 0
111+
br i1 %c, label %outer.header, label %loop.latch
112+
113+
loop.latch:
114+
%iv.next = add i64 %iv, 1
115+
%ec = icmp eq i64 %iv.next, 1024
116+
br i1 %ec, label %exit, label %loop.header
117+
118+
exit:
119+
ret i32 1
120+
}

0 commit comments

Comments
 (0)