@@ -43,10 +43,15 @@ static SmallVector<Value *, 4> getOperand(ArrayRef<Value *> Bndl,
43
43
return Operands;
44
44
}
45
45
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 ();
50
55
return std::next (BotI->getIterator ());
51
56
}
52
57
@@ -61,7 +66,8 @@ Value *BottomUpVec::createVectorInstr(ArrayRef<Value *> Bndl,
61
66
Type *ScalarTy = VecUtils::getElementType (Utils::getExpectedType (Bndl[0 ]));
62
67
auto *VecTy = VecUtils::getWideType (ScalarTy, VecUtils::getNumLanes (Bndl));
63
68
64
- BasicBlock::iterator WhereIt = getInsertPointAfterInstrs (Bndl);
69
+ BasicBlock::iterator WhereIt = getInsertPointAfterInstrs (
70
+ Bndl, cast<Instruction>(Bndl[0 ])->getParent ());
65
71
66
72
auto Opcode = cast<Instruction>(Bndl[0 ])->getOpcode ();
67
73
switch (Opcode) {
@@ -175,14 +181,15 @@ void BottomUpVec::tryEraseDeadInstrs() {
175
181
DeadInstrCandidates.clear ();
176
182
}
177
183
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);
180
187
return ShuffleVectorInst::create (VecOp, VecOp, Mask, WhereIt,
181
188
VecOp->getContext (), " VShuf" );
182
189
}
183
190
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 );
186
193
187
194
Type *ScalarTy = VecUtils::getCommonScalarType (ToPack);
188
195
unsigned Lanes = VecUtils::getNumLanes (ToPack);
@@ -258,8 +265,12 @@ void BottomUpVec::collectPotentiallyDeadInstrs(ArrayRef<Value *> Bndl) {
258
265
}
259
266
}
260
267
261
- Value *BottomUpVec::vectorizeRec (ArrayRef<Value *> Bndl, unsigned Depth) {
268
+ Value *BottomUpVec::vectorizeRec (ArrayRef<Value *> Bndl,
269
+ ArrayRef<Value *> UserBndl, unsigned Depth) {
262
270
Value *NewVec = nullptr ;
271
+ auto *UserBB = !UserBndl.empty ()
272
+ ? cast<Instruction>(UserBndl.front ())->getParent ()
273
+ : cast<Instruction>(Bndl[0 ])->getParent ();
263
274
const auto &LegalityRes = Legality->canVectorize (Bndl);
264
275
switch (LegalityRes.getSubclassID ()) {
265
276
case LegalityResultID::Widen: {
@@ -272,15 +283,15 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
272
283
break ;
273
284
case Instruction::Opcode::Store: {
274
285
// 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 );
276
287
VecOperands.push_back (VecOp);
277
288
VecOperands.push_back (cast<StoreInst>(I)->getPointerOperand ());
278
289
break ;
279
290
}
280
291
default :
281
292
// Visit all operands.
282
293
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 );
284
295
VecOperands.push_back (VecOp);
285
296
}
286
297
break ;
@@ -301,7 +312,7 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
301
312
auto *VecOp = cast<DiamondReuseWithShuffle>(LegalityRes).getVector ();
302
313
const ShuffleMask &Mask =
303
314
cast<DiamondReuseWithShuffle>(LegalityRes).getMask ();
304
- NewVec = createShuffle (VecOp, Mask);
315
+ NewVec = createShuffle (VecOp, Mask, UserBB );
305
316
break ;
306
317
}
307
318
case LegalityResultID::DiamondReuseMultiInput: {
@@ -315,7 +326,8 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
315
326
if (auto *I = dyn_cast<Instruction>(ElmDescr.getValue ()))
316
327
DescrInstrs.push_back (I);
317
328
}
318
- auto WhereIt = getInsertPointAfterInstrs (DescrInstrs);
329
+ BasicBlock::iterator WhereIt =
330
+ getInsertPointAfterInstrs (DescrInstrs, UserBB);
319
331
320
332
Value *LastV = PoisonValue::get (ResTy);
321
333
for (auto [Lane, ElmDescr] : enumerate(Descr.getDescrs ())) {
@@ -342,7 +354,7 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
342
354
// If we can't vectorize the seeds then just return.
343
355
if (Depth == 0 )
344
356
return nullptr ;
345
- NewVec = createPack (Bndl);
357
+ NewVec = createPack (Bndl, UserBB );
346
358
break ;
347
359
}
348
360
}
@@ -352,7 +364,7 @@ Value *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl, unsigned Depth) {
352
364
bool BottomUpVec::tryVectorize (ArrayRef<Value *> Bndl) {
353
365
DeadInstrCandidates.clear ();
354
366
Legality->clear ();
355
- vectorizeRec (Bndl, /* Depth=*/ 0 );
367
+ vectorizeRec (Bndl, {}, /* Depth=*/ 0 );
356
368
tryEraseDeadInstrs ();
357
369
return Change;
358
370
}
0 commit comments