@@ -1020,6 +1020,8 @@ static bool allSameType(ArrayRef<Value *> VL) {
10201020/// possible scalar operand in vectorized instruction.
10211021static bool doesInTreeUserNeedToExtract(Value *Scalar, Instruction *UserInst,
10221022 TargetLibraryInfo *TLI) {
1023+ if (!UserInst)
1024+ return false;
10231025 unsigned Opcode = UserInst->getOpcode();
10241026 switch (Opcode) {
10251027 case Instruction::Load: {
@@ -2809,6 +2811,11 @@ class BoUpSLP {
28092811 /// \ returns the graph entry for the \p Idx operand of the \p E entry.
28102812 const TreeEntry *getOperandEntry(const TreeEntry *E, unsigned Idx) const;
28112813
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+
28122819 /// \returns Cast context for the given graph node.
28132820 TargetTransformInfo::CastContextHint
28142821 getCastContextHint(const TreeEntry &TE) const;
@@ -5987,6 +5994,15 @@ void BoUpSLP::reorderBottomToTop(bool IgnoreReorder) {
59875994 VectorizableTree.front()->ReorderIndices.clear();
59885995}
59895996
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+
59906006void BoUpSLP::buildExternalUses(
59916007 const ExtraValueToDebugLocsMap &ExternallyUsedValues) {
59926008 DenseMap<Value *, unsigned> ScalarToExtUses;
@@ -6036,7 +6052,7 @@ void BoUpSLP::buildExternalUses(
60366052 // be used.
60376053 if (UseEntry->State == TreeEntry::ScatterVectorize ||
60386054 !doesInTreeUserNeedToExtract(
6039- Scalar, cast<Instruction>( UseEntry->Scalars.front() ), TLI)) {
6055+ Scalar, getRootEntryInstruction(* UseEntry), TLI)) {
60406056 LLVM_DEBUG(dbgs() << "SLP: \tInternal user will be removed:" << *U
60416057 << ".\n");
60426058 assert(!UseEntry->isGather() && "Bad state");
@@ -8450,8 +8466,8 @@ void BoUpSLP::transformNodes() {
84508466 Instruction::Store, VecTy, BaseSI->getPointerOperand(),
84518467 /*VariableMask=*/false, CommonAlignment, CostKind, BaseSI);
84528468 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 .
84558471 E.State = TreeEntry::StridedVectorize;
84568472 }
84578473 break;
@@ -13776,7 +13792,7 @@ Value *BoUpSLP::vectorizeTree(TreeEntry *E, bool PostponedPHIs) {
1377613792 ST = Builder.CreateAlignedStore(VecValue, Ptr, SI->getAlign());
1377713793 } else {
1377813794 assert(E->State == TreeEntry::StridedVectorize &&
13779- "Expected either strided or conseutive stores.");
13795+ "Expected either strided or consecutive stores.");
1378013796 if (!E->ReorderIndices.empty()) {
1378113797 SI = cast<StoreInst>(E->Scalars[E->ReorderIndices.front()]);
1378213798 Ptr = SI->getPointerOperand();
@@ -14380,8 +14396,7 @@ Value *BoUpSLP::vectorizeTree(
1438014396 (E->State == TreeEntry::Vectorize ||
1438114397 E->State == TreeEntry::StridedVectorize) &&
1438214398 doesInTreeUserNeedToExtract(
14383- Scalar,
14384- cast<Instruction>(UseEntry->Scalars.front()),
14399+ Scalar, getRootEntryInstruction(*UseEntry),
1438514400 TLI);
1438614401 })) &&
1438714402 "Scalar with nullptr User must be registered in "
0 commit comments