Skip to content

Commit c7053ac

Browse files
authored
[SandboxVec][BottomUpVec] Disable crossing BBs (#124039)
Crossing BBs is not currently supported by the structures of the vectorizer. This patch fixes instances where this was happening, including: - a walk of use-def operands that updates the UnscheduledSuccs counter, - the dead instruction removal is now done per BB, - the scheduler, which will reject bundles that cross BBs.
1 parent 621e5cd commit c7053ac

File tree

4 files changed

+51
-8
lines changed

4 files changed

+51
-8
lines changed

llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,9 @@ void DependencyGraph::setDefUseUnscheduledSuccs(
232232
auto *OpI = dyn_cast<Instruction>(Op);
233233
if (OpI == nullptr)
234234
continue;
235+
// TODO: For now don't cross BBs.
236+
if (OpI->getParent() != I.getParent())
237+
continue;
235238
if (!NewInterval.contains(OpI))
236239
continue;
237240
auto *OpN = getNode(OpI);

llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -169,14 +169,19 @@ Value *BottomUpVec::createVectorInstr(ArrayRef<Value *> Bndl,
169169
}
170170

171171
void BottomUpVec::tryEraseDeadInstrs() {
172-
// Visiting the dead instructions bottom-to-top.
173-
SmallVector<Instruction *> SortedDeadInstrCandidates(
174-
DeadInstrCandidates.begin(), DeadInstrCandidates.end());
175-
sort(SortedDeadInstrCandidates,
176-
[](Instruction *I1, Instruction *I2) { return I1->comesBefore(I2); });
177-
for (Instruction *I : reverse(SortedDeadInstrCandidates)) {
178-
if (I->hasNUses(0))
179-
I->eraseFromParent();
172+
DenseMap<BasicBlock *, SmallVector<Instruction *>> SortedDeadInstrCandidates;
173+
// The dead instrs could span BBs, so we need to collect and sort them per BB.
174+
for (auto *DeadI : DeadInstrCandidates)
175+
SortedDeadInstrCandidates[DeadI->getParent()].push_back(DeadI);
176+
for (auto &Pair : SortedDeadInstrCandidates)
177+
sort(Pair.second,
178+
[](Instruction *I1, Instruction *I2) { return I1->comesBefore(I2); });
179+
for (const auto &Pair : SortedDeadInstrCandidates) {
180+
for (Instruction *I : reverse(Pair.second)) {
181+
if (I->hasNUses(0))
182+
// Erase the dead instructions bottom-to-top.
183+
I->eraseFromParent();
184+
}
180185
}
181186
DeadInstrCandidates.clear();
182187
}

llvm/lib/Transforms/Vectorize/SandboxVectorizer/Scheduler.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,13 @@ bool Scheduler::trySchedule(ArrayRef<Instruction *> Instrs) {
206206
// We start scheduling at the bottom instr of Instrs.
207207
ScheduleTopItOpt = std::next(VecUtils::getLowest(Instrs)->getIterator());
208208

209+
// TODO: For now don't cross BBs.
210+
if (!DAG.getInterval().empty()) {
211+
auto *BB = DAG.getInterval().top()->getParent();
212+
if (any_of(Instrs, [BB](auto *I) { return I->getParent() != BB; }))
213+
return false;
214+
}
215+
209216
// Extend the DAG to include Instrs.
210217
Interval<Instruction> Extension = DAG.extend(Instrs);
211218
// Add nodes to ready list.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="bottom-up-vec<>" %s -S | FileCheck %s
3+
4+
define void @cross_bbs(ptr %ptr) {
5+
; CHECK-LABEL: define void @cross_bbs(
6+
; CHECK-SAME: ptr [[PTR:%.*]]) {
7+
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr i8, ptr [[PTR]], i32 0
8+
; CHECK-NEXT: [[PTR1:%.*]] = getelementptr i8, ptr [[PTR]], i32 1
9+
; CHECK-NEXT: [[L0:%.*]] = load i8, ptr [[PTR0]], align 1
10+
; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[PTR1]], align 1
11+
; CHECK-NEXT: [[PACK:%.*]] = insertelement <2 x i8> poison, i8 [[L0]], i32 0
12+
; CHECK-NEXT: [[PACK1:%.*]] = insertelement <2 x i8> [[PACK]], i8 [[L1]], i32 1
13+
; CHECK-NEXT: br label %[[BB:.*]]
14+
; CHECK: [[BB]]:
15+
; CHECK-NEXT: store <2 x i8> [[PACK1]], ptr [[PTR0]], align 1
16+
; CHECK-NEXT: ret void
17+
;
18+
%ptr0 = getelementptr i8, ptr %ptr, i32 0
19+
%ptr1 = getelementptr i8, ptr %ptr, i32 1
20+
%l0 = load i8, ptr %ptr0
21+
%l1 = load i8, ptr %ptr1
22+
br label %bb
23+
24+
bb:
25+
store i8 %l0, ptr %ptr0
26+
store i8 %l1, ptr %ptr1
27+
ret void
28+
}

0 commit comments

Comments
 (0)