Skip to content

Commit 8110af7

Browse files
authored
[SandboxVec][BottomUpVec] Fix codegen when packing constants. (#124033)
Before this patch packing a bundle of constants would crash because `getInsertPointAfterInstrs()` expected instructions. This patch fixes this.
1 parent 8f45452 commit 8110af7

File tree

3 files changed

+52
-20
lines changed
  • llvm
    • include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes
    • lib/Transforms/Vectorize/SandboxVectorizer/Passes
    • test/Transforms/SandboxVectorizer

3 files changed

+52
-20
lines changed

llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,20 @@ class BottomUpVec final : public FunctionPass {
3838
/// collected during vectorization.
3939
void tryEraseDeadInstrs();
4040
/// Creates a shuffle instruction that shuffles \p VecOp according to \p Mask.
41-
Value *createShuffle(Value *VecOp, const ShuffleMask &Mask);
42-
/// Packs all elements of \p ToPack into a vector and returns that vector.
43-
Value *createPack(ArrayRef<Value *> ToPack);
41+
/// \p UserBB is the block of the user bundle.
42+
Value *createShuffle(Value *VecOp, const ShuffleMask &Mask,
43+
BasicBlock *UserBB);
44+
/// Packs all elements of \p ToPack into a vector and returns that vector. \p
45+
/// UserBB is the block of the user bundle.
46+
Value *createPack(ArrayRef<Value *> ToPack, BasicBlock *UserBB);
4447
/// After we create vectors for groups of instructions, the original
4548
/// instructions are potentially dead and may need to be removed. This
4649
/// function helps collect these instructions (along with the pointer operands
4750
/// for loads/stores) so that they can be cleaned up later.
4851
void collectPotentiallyDeadInstrs(ArrayRef<Value *> Bndl);
4952
/// Recursively try to vectorize \p Bndl and its operands.
50-
Value *vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth);
53+
Value *vectorizeRec(ArrayRef<Value *> Bndl, ArrayRef<Value *> UserBndl,
54+
unsigned Depth);
5155
/// Entry point for vectorization starting from \p Seeds.
5256
bool tryVectorize(ArrayRef<Value *> Seeds);
5357

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

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,15 @@ static SmallVector<Value *, 4> getOperand(ArrayRef<Value *> Bndl,
4343
return Operands;
4444
}
4545

46-
static BasicBlock::iterator
47-
getInsertPointAfterInstrs(ArrayRef<Value *> Instrs) {
48-
auto *BotI = VecUtils::getLowest(Instrs);
49-
// If Bndl contains Arguments or Constants, use the beginning of the BB.
46+
/// \Returns the BB iterator after the lowest instruction in \p Vals, or the top
47+
/// of BB if no instruction found in \p Vals.
48+
static BasicBlock::iterator getInsertPointAfterInstrs(ArrayRef<Value *> Vals,
49+
BasicBlock *BB) {
50+
auto *BotI = VecUtils::getLowest(Vals);
51+
if (BotI == nullptr)
52+
// We are using BB->begin() as the fallback insert point if `ToPack` did
53+
// not contain instructions.
54+
return BB->begin();
5055
return std::next(BotI->getIterator());
5156
}
5257

@@ -61,7 +66,8 @@ Value *BottomUpVec::createVectorInstr(ArrayRef<Value *> Bndl,
6166
Type *ScalarTy = VecUtils::getElementType(Utils::getExpectedType(Bndl[0]));
6267
auto *VecTy = VecUtils::getWideType(ScalarTy, VecUtils::getNumLanes(Bndl));
6368

64-
BasicBlock::iterator WhereIt = getInsertPointAfterInstrs(Bndl);
69+
BasicBlock::iterator WhereIt = getInsertPointAfterInstrs(
70+
Bndl, cast<Instruction>(Bndl[0])->getParent());
6571

6672
auto Opcode = cast<Instruction>(Bndl[0])->getOpcode();
6773
switch (Opcode) {
@@ -175,14 +181,15 @@ void BottomUpVec::tryEraseDeadInstrs() {
175181
DeadInstrCandidates.clear();
176182
}
177183

178-
Value *BottomUpVec::createShuffle(Value *VecOp, const ShuffleMask &Mask) {
179-
BasicBlock::iterator WhereIt = getInsertPointAfterInstrs({VecOp});
184+
Value *BottomUpVec::createShuffle(Value *VecOp, const ShuffleMask &Mask,
185+
BasicBlock *UserBB) {
186+
BasicBlock::iterator WhereIt = getInsertPointAfterInstrs({VecOp}, UserBB);
180187
return ShuffleVectorInst::create(VecOp, VecOp, Mask, WhereIt,
181188
VecOp->getContext(), "VShuf");
182189
}
183190

184-
Value *BottomUpVec::createPack(ArrayRef<Value *> ToPack) {
185-
BasicBlock::iterator WhereIt = getInsertPointAfterInstrs(ToPack);
191+
Value *BottomUpVec::createPack(ArrayRef<Value *> ToPack, BasicBlock *UserBB) {
192+
BasicBlock::iterator WhereIt = getInsertPointAfterInstrs(ToPack, UserBB);
186193

187194
Type *ScalarTy = VecUtils::getCommonScalarType(ToPack);
188195
unsigned Lanes = VecUtils::getNumLanes(ToPack);
@@ -258,8 +265,12 @@ void BottomUpVec::collectPotentiallyDeadInstrs(ArrayRef<Value *> Bndl) {
258265
}
259266
}
260267

261-
Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
268+
Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl,
269+
ArrayRef<Value *> UserBndl, unsigned Depth) {
262270
Value *NewVec = nullptr;
271+
auto *UserBB = !UserBndl.empty()
272+
? cast<Instruction>(UserBndl.front())->getParent()
273+
: cast<Instruction>(Bndl[0])->getParent();
263274
const auto &LegalityRes = Legality->canVectorize(Bndl);
264275
switch (LegalityRes.getSubclassID()) {
265276
case LegalityResultID::Widen: {
@@ -272,15 +283,15 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
272283
break;
273284
case Instruction::Opcode::Store: {
274285
// Don't recurse towards the pointer operand.
275-
auto *VecOp = vectorizeRec(getOperand(Bndl, 0), Depth + 1);
286+
auto *VecOp = vectorizeRec(getOperand(Bndl, 0), Bndl, Depth + 1);
276287
VecOperands.push_back(VecOp);
277288
VecOperands.push_back(cast<StoreInst>(I)->getPointerOperand());
278289
break;
279290
}
280291
default:
281292
// Visit all operands.
282293
for (auto OpIdx : seq<unsigned>(I->getNumOperands())) {
283-
auto *VecOp = vectorizeRec(getOperand(Bndl, OpIdx), Depth + 1);
294+
auto *VecOp = vectorizeRec(getOperand(Bndl, OpIdx), Bndl, Depth + 1);
284295
VecOperands.push_back(VecOp);
285296
}
286297
break;
@@ -301,7 +312,7 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
301312
auto *VecOp = cast<DiamondReuseWithShuffle>(LegalityRes).getVector();
302313
const ShuffleMask &Mask =
303314
cast<DiamondReuseWithShuffle>(LegalityRes).getMask();
304-
NewVec = createShuffle(VecOp, Mask);
315+
NewVec = createShuffle(VecOp, Mask, UserBB);
305316
break;
306317
}
307318
case LegalityResultID::DiamondReuseMultiInput: {
@@ -315,7 +326,8 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
315326
if (auto *I = dyn_cast<Instruction>(ElmDescr.getValue()))
316327
DescrInstrs.push_back(I);
317328
}
318-
auto WhereIt = getInsertPointAfterInstrs(DescrInstrs);
329+
BasicBlock::iterator WhereIt =
330+
getInsertPointAfterInstrs(DescrInstrs, UserBB);
319331

320332
Value *LastV = PoisonValue::get(ResTy);
321333
for (auto [Lane, ElmDescr] : enumerate(Descr.getDescrs())) {
@@ -342,7 +354,7 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
342354
// If we can't vectorize the seeds then just return.
343355
if (Depth == 0)
344356
return nullptr;
345-
NewVec = createPack(Bndl);
357+
NewVec = createPack(Bndl, UserBB);
346358
break;
347359
}
348360
}
@@ -352,7 +364,7 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
352364
bool BottomUpVec::tryVectorize(ArrayRef<Value *> Bndl) {
353365
DeadInstrCandidates.clear();
354366
Legality->clear();
355-
vectorizeRec(Bndl, /*Depth=*/0);
367+
vectorizeRec(Bndl, {}, /*Depth=*/0);
356368
tryEraseDeadInstrs();
357369
return Change;
358370
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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 @pack_constants(ptr %ptr) {
5+
; CHECK-LABEL: define void @pack_constants(
6+
; CHECK-SAME: ptr [[PTR:%.*]]) {
7+
; CHECK-NEXT: [[PTR0:%.*]] = getelementptr i8, ptr [[PTR]], i32 0
8+
; CHECK-NEXT: store <2 x i8> <i8 0, i8 1>, ptr [[PTR0]], align 1
9+
; CHECK-NEXT: ret void
10+
;
11+
%ptr0 = getelementptr i8, ptr %ptr, i32 0
12+
%ptr1 = getelementptr i8, ptr %ptr, i32 1
13+
store i8 0, ptr %ptr0
14+
store i8 1, ptr %ptr1
15+
ret void
16+
}

0 commit comments

Comments
 (0)