Skip to content

Commit 150b51f

Browse files
committed
[LV] Support generating masks for switch terminators.
Update createEdgeMask to created masks where the terminator in Src is a switch. We need to handle 2 separate cases: 1. Dst is not the default desintation. Dst is reached if any of the cases with destination == Dst are taken. Join the conditions for each case where destination == Dst using a logical OR. 2. Dst is the default destination. Dst is reached if none of the cases with destination != Dst are taken. Join the conditions for each case where the destination is != Dst using a logical OR and negate it. Fixes #48188.
1 parent 8557035 commit 150b51f

File tree

8 files changed

+1302
-70
lines changed

8 files changed

+1302
-70
lines changed

clang/test/Frontend/optimization-remark-analysis.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %clang -O1 -fvectorize -target x86_64-unknown-unknown -emit-llvm -Rpass-analysis -S %s -o - 2>&1 | FileCheck %s --check-prefix=RPASS
22
// RUN: %clang -O1 -fvectorize -target x86_64-unknown-unknown -emit-llvm -S %s -o - 2>&1 | FileCheck %s
33

4-
// RPASS: {{.*}}:12:5: remark: loop not vectorized: loop contains a switch statement
4+
// RPASS-NOT: {{.*}}:12:5: remark: loop not vectorized
55
// CHECK-NOT: remark: loop not vectorized: loop contains a switch statement
66

77
double foo(int N, int *Array) {

llvm/lib/Transforms/Vectorize/LoopVectorizationLegality.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,11 +1340,11 @@ bool LoopVectorizationLegality::canVectorizeWithIfConvert() {
13401340
// Collect the blocks that need predication.
13411341
for (BasicBlock *BB : TheLoop->blocks()) {
13421342
// We don't support switch statements inside loops.
1343-
if (!isa<BranchInst>(BB->getTerminator())) {
1344-
reportVectorizationFailure("Loop contains a switch statement",
1345-
"loop contains a switch statement",
1346-
"LoopContainsSwitch", ORE, TheLoop,
1347-
BB->getTerminator());
1343+
if (!isa<BranchInst, SwitchInst>(BB->getTerminator())) {
1344+
reportVectorizationFailure("Loop contains an unsupported termaintor",
1345+
"loop contains an unsupported terminator",
1346+
"LoopContainsUnsupportedTerminator", ORE,
1347+
TheLoop, BB->getTerminator());
13481348
return false;
13491349
}
13501350

llvm/lib/Transforms/Vectorize/LoopVectorize.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7842,6 +7842,41 @@ VPValue *VPRecipeBuilder::createEdgeMask(BasicBlock *Src, BasicBlock *Dst) {
78427842

78437843
VPValue *SrcMask = getBlockInMask(Src);
78447844

7845+
if (auto *SI = dyn_cast<SwitchInst>(Src->getTerminator())) {
7846+
// Create mask where the terminator in Src is a switch. We need to handle 2
7847+
// separate cases:
7848+
// 1. Dst is not the default desintation. Dst is reached if any of the cases
7849+
// with destination == Dst are taken. Join the conditions for each case
7850+
// where destination == Dst using a logical OR.
7851+
// 2. Dst is the default destination. Dst is reached if none of the cases
7852+
// with destination != Dst are taken. Join the conditions for each case
7853+
// where the destination is != Dst using a logical OR and negate it.
7854+
VPValue *Mask = nullptr;
7855+
VPValue *Cond = getVPValueOrAddLiveIn(SI->getCondition(), Plan);
7856+
bool IsDefault = SI->getDefaultDest() == Dst;
7857+
for (auto &C : SI->cases()) {
7858+
if (IsDefault) {
7859+
if (C.getCaseSuccessor() == Dst)
7860+
continue;
7861+
} else if (C.getCaseSuccessor() != Dst)
7862+
continue;
7863+
7864+
VPValue *Eq = EdgeMaskCache.lookup({Src, C.getCaseSuccessor()});
7865+
if (!Eq) {
7866+
VPValue *V = getVPValueOrAddLiveIn(C.getCaseValue(), Plan);
7867+
Eq = Builder.createICmp(CmpInst::ICMP_EQ, Cond, V);
7868+
}
7869+
if (Mask)
7870+
Mask = Builder.createOr(Mask, Eq);
7871+
else
7872+
Mask = Eq;
7873+
}
7874+
if (IsDefault)
7875+
Mask = Builder.createNot(Mask);
7876+
assert(Mask && "mask must be created");
7877+
return EdgeMaskCache[Edge] = Mask;
7878+
}
7879+
78457880
// The terminator has to be a branch inst!
78467881
BranchInst *BI = dyn_cast<BranchInst>(Src->getTerminator());
78477882
assert(BI && "Unexpected terminator found");

llvm/test/Transforms/LoopVectorize/X86/predicate-switch.ll

Lines changed: 771 additions & 29 deletions
Large diffs are not rendered by default.

llvm/test/Transforms/LoopVectorize/no_switch.ll

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@
22
; RUN: opt < %s -passes=loop-vectorize,transform-warning -force-vector-width=1 -S 2>&1 | FileCheck %s -check-prefix=NOANALYSIS
33
; RUN: opt < %s -passes=loop-vectorize,transform-warning -force-vector-width=4 -pass-remarks-missed='loop-vectorize' -S 2>&1 | FileCheck %s -check-prefix=MOREINFO
44

5-
; CHECK: remark: source.cpp:4:5: loop not vectorized: loop contains a switch statement
6-
; CHECK: warning: source.cpp:4:5: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
5+
; CHECK-NOT: loop not vectorized: loop contains a switch statement
6+
; CHECK-NOT: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
77

88
; NOANALYSIS-NOT: remark: {{.*}}
9-
; NOANALYSIS: warning: source.cpp:4:5: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
9+
; NOANALYSIS: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
1010

11-
; MOREINFO: remark: source.cpp:4:5: loop not vectorized: loop contains a switch statement
12-
; MOREINFO: remark: source.cpp:4:5: loop not vectorized (Force=true, Vector Width=4)
13-
; MOREINFO: warning: source.cpp:4:5: loop not vectorized: the optimizer was unable to perform the requested transformation; the transformation might be disabled or specified as part of an unsupported transformation ordering
11+
; MOREINFO-NOT: remark
1412

1513
; CHECK: _Z11test_switchPii
16-
; CHECK-NOT: x i32>
14+
; CHECK: vector.body:
1715
; CHECK: ret
1816

1917
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"

0 commit comments

Comments
 (0)