@@ -1020,6 +1020,8 @@ static bool allSameType(ArrayRef<Value *> VL) {
1020
1020
/// possible scalar operand in vectorized instruction.
1021
1021
static bool doesInTreeUserNeedToExtract(Value *Scalar, Instruction *UserInst,
1022
1022
TargetLibraryInfo *TLI) {
1023
+ if (!UserInst)
1024
+ return false;
1023
1025
unsigned Opcode = UserInst->getOpcode();
1024
1026
switch (Opcode) {
1025
1027
case Instruction::Load: {
@@ -2809,6 +2811,11 @@ class BoUpSLP {
2809
2811
/// \ returns the graph entry for the \p Idx operand of the \p E entry.
2810
2812
const TreeEntry *getOperandEntry(const TreeEntry *E, unsigned Idx) const;
2811
2813
2814
+ /// Gets the root instruction for the given node. If the node is a strided
2815
+ /// load/store node with the reverse order, the root instruction is the last
2816
+ /// one.
2817
+ Instruction *getRootEntryInstruction(const TreeEntry &Entry) const;
2818
+
2812
2819
/// \returns Cast context for the given graph node.
2813
2820
TargetTransformInfo::CastContextHint
2814
2821
getCastContextHint(const TreeEntry &TE) const;
@@ -5987,6 +5994,15 @@ void BoUpSLP::reorderBottomToTop(bool IgnoreReorder) {
5987
5994
VectorizableTree.front()->ReorderIndices.clear();
5988
5995
}
5989
5996
5997
+ Instruction *BoUpSLP::getRootEntryInstruction(const TreeEntry &Entry) const {
5998
+ if ((Entry.getOpcode() == Instruction::Store ||
5999
+ Entry.getOpcode() == Instruction::Load) &&
6000
+ Entry.State == TreeEntry::StridedVectorize &&
6001
+ !Entry.ReorderIndices.empty() && isReverseOrder(Entry.ReorderIndices))
6002
+ return dyn_cast<Instruction>(Entry.Scalars[Entry.ReorderIndices.front()]);
6003
+ return dyn_cast<Instruction>(Entry.Scalars.front());
6004
+ }
6005
+
5990
6006
void BoUpSLP::buildExternalUses(
5991
6007
const ExtraValueToDebugLocsMap &ExternallyUsedValues) {
5992
6008
DenseMap<Value *, unsigned> ScalarToExtUses;
@@ -6036,7 +6052,7 @@ void BoUpSLP::buildExternalUses(
6036
6052
// be used.
6037
6053
if (UseEntry->State == TreeEntry::ScatterVectorize ||
6038
6054
!doesInTreeUserNeedToExtract(
6039
- Scalar, cast<Instruction>( UseEntry->Scalars.front() ), TLI)) {
6055
+ Scalar, getRootEntryInstruction(* UseEntry), TLI)) {
6040
6056
LLVM_DEBUG(dbgs() << "SLP: \tInternal user will be removed:" << *U
6041
6057
<< ".\n");
6042
6058
assert(!UseEntry->isGather() && "Bad state");
@@ -8450,8 +8466,8 @@ void BoUpSLP::transformNodes() {
8450
8466
Instruction::Store, VecTy, BaseSI->getPointerOperand(),
8451
8467
/*VariableMask=*/false, CommonAlignment, CostKind, BaseSI);
8452
8468
if (StridedCost < OriginalVecCost)
8453
- // Strided load is more profitable than consecutive load + reverse -
8454
- // transform the node to strided load .
8469
+ // Strided store is more profitable than reverse + consecutive store -
8470
+ // transform the node to strided store .
8455
8471
E.State = TreeEntry::StridedVectorize;
8456
8472
}
8457
8473
break;
@@ -13776,7 +13792,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {
13776
13792
ST = Builder.CreateAlignedStore(VecValue, Ptr, SI->getAlign());
13777
13793
} else {
13778
13794
assert(E->State == TreeEntry::StridedVectorize &&
13779
- "Expected either strided or conseutive stores.");
13795
+ "Expected either strided or consecutive stores.");
13780
13796
if (!E->ReorderIndices.empty()) {
13781
13797
SI = cast<StoreInst>(E->Scalars[E->ReorderIndices.front()]);
13782
13798
Ptr = SI->getPointerOperand();
@@ -14380,8 +14396,7 @@ Value *BoUpSLP::vectorizeTree(
14380
14396
(E->State == TreeEntry::Vectorize ||
14381
14397
E->State == TreeEntry::StridedVectorize) &&
14382
14398
doesInTreeUserNeedToExtract(
14383
- Scalar,
14384
- cast<Instruction>(UseEntry->Scalars.front()),
14399
+ Scalar, getRootEntryInstruction(*UseEntry),
14385
14400
TLI);
14386
14401
})) &&
14387
14402
"Scalar with nullptr User must be registered in "
0 commit comments