Skip to content

Commit 5e3ac2a

Browse files
committed
[LV] Bail out on loops with switch as latch terminator.
Currently we cannot vectorize loops with latch blocks terminated by a switch. In the future this could be handled by materializing appropriate compares. Fixes llvm#156894.
1 parent e6358ab commit 5e3ac2a

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,6 +1642,19 @@ bool LoopVectorizationLegality::canVectorizeLoopCFG(Loop *Lp,
16421642
return false;
16431643
}
16441644

1645+
// The latch must be terminated by a BranchInst.
1646+
BasicBlock *Latch = Lp->getLoopLatch();
1647+
if (Latch && !isa<BranchInst>(Latch->getTerminator())) {
1648+
reportVectorizationFailure(
1649+
"The loop latch terminator is not a BranchInst",
1650+
"loop control flow is not understood by vectorizer", "CFGNotUnderstood",
1651+
ORE, TheLoop);
1652+
if (DoExtraAnalysis)
1653+
Result = false;
1654+
else
1655+
return false;
1656+
}
1657+
16451658
return Result;
16461659
}
16471660

llvm/test/Transforms/LoopVectorize/loop-form.ll

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,3 +1374,49 @@ exit.1:
13741374
exit.2:
13751375
ret i16 1
13761376
}
1377+
1378+
; Loop with a switch terminator in the latch block. Cannot be vectorized
1379+
; currently.
1380+
; Test case for https://github.com/llvm/llvm-project/issues/156894.
1381+
define void @switch_in_latch(ptr %a) {
1382+
; CHECK-LABEL: @switch_in_latch(
1383+
; CHECK-NEXT: entry:
1384+
; CHECK-NEXT: br label [[LOOP:%.*]]
1385+
; CHECK: loop:
1386+
; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1387+
; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A:%.*]], i32 [[IV]]
1388+
; CHECK-NEXT: store i32 1, ptr [[GEP]], align 4
1389+
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
1390+
; CHECK-NEXT: switch i32 [[IV_NEXT]], label [[LOOP]] [
1391+
; CHECK-NEXT: i32 100, label [[EXIT:%.*]]
1392+
; CHECK-NEXT: ]
1393+
; CHECK: exit:
1394+
; CHECK-NEXT: ret void
1395+
;
1396+
; TAILFOLD-LABEL: @switch_in_latch(
1397+
; TAILFOLD-NEXT: entry:
1398+
; TAILFOLD-NEXT: br label [[LOOP:%.*]]
1399+
; TAILFOLD: loop:
1400+
; TAILFOLD-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
1401+
; TAILFOLD-NEXT: [[GEP:%.*]] = getelementptr i32, ptr [[A:%.*]], i32 [[IV]]
1402+
; TAILFOLD-NEXT: store i32 1, ptr [[GEP]], align 4
1403+
; TAILFOLD-NEXT: [[IV_NEXT]] = add i32 [[IV]], 1
1404+
; TAILFOLD-NEXT: switch i32 [[IV_NEXT]], label [[LOOP]] [
1405+
; TAILFOLD-NEXT: i32 100, label [[EXIT:%.*]]
1406+
; TAILFOLD-NEXT: ]
1407+
; TAILFOLD: exit:
1408+
; TAILFOLD-NEXT: ret void
1409+
;
1410+
entry:
1411+
br label %loop
1412+
1413+
loop:
1414+
%iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ]
1415+
%gep = getelementptr i32, ptr %a, i32 %iv
1416+
store i32 1, ptr %gep, align 4
1417+
%iv.next = add i32 %iv, 1
1418+
switch i32 %iv.next, label %loop [i32 100, label %exit]
1419+
1420+
exit:
1421+
ret void
1422+
}

0 commit comments

Comments
 (0)