@@ -6918,8 +6918,8 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69186918 const SmallVectorImpl<unsigned> &SortedIndices, const int64_t Diff, Value *Ptr0,
69196919 Value *PtrN, StridedPtrInfo &SPtrInfo) const {
69206920 const unsigned Sz = PointerOps.size();
6921- SmallVector<int64_t> SortedOffsetsFromBase;
6922- SortedOffsetsFromBase.resize(Sz);
6921+ SmallVector<int64_t> SortedOffsetsFromBase(Sz) ;
6922+ // Go through `PointerOps` in sorted order and record offsets from `Ptr0`.
69236923 for (unsigned I : seq<unsigned>(Sz)) {
69246924 Value *Ptr =
69256925 SortedIndices.empty() ? PointerOps[I] : PointerOps[SortedIndices[I]];
@@ -6928,10 +6928,24 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69286928 }
69296929 assert(SortedOffsetsFromBase.size() > 1 &&
69306930 "Trying to generate strided load for less than 2 loads");
6931- //
6932- // Find where the first group ends.
6931+ // The code below checks that `SortedOffsetsFromBase` looks as follows:
6932+ // ```
6933+ // [
6934+ // (e_{0, 0}, e_{0, 1}, ..., e_{0, GroupSize - 1}), // first group
6935+ // (e_{1, 0}, e_{1, 1}, ..., e_{1, GroupSize - 1}), // secon group
6936+ // ...
6937+ // (e_{NumGroups - 1, 0}, e_{NumGroups - 1, 1}, ..., e_{NumGroups - 1,
6938+ // GroupSize - 1}), // last group
6939+ // ]
6940+ // ```
6941+ // The distance between consecutive elements within each group should all be
6942+ // the same `StrideWithinGroup`. The distance between the first elements of
6943+ // consecutive groups should all be the same `StrideBetweenGroups`.
6944+
69336945 int64_t StrideWithinGroup =
69346946 SortedOffsetsFromBase[1] - SortedOffsetsFromBase[0];
6947+ // Determine size of the first group. Later we will check that all other
6948+ // groups have the same size.
69356949 unsigned GroupSize = 1;
69366950 for (; GroupSize != SortedOffsetsFromBase.size(); ++GroupSize) {
69376951 if (SortedOffsetsFromBase[GroupSize] -
@@ -6944,6 +6958,8 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69446958 int64_t StrideIntVal = StrideWithinGroup;
69456959 FixedVectorType *StridedLoadTy = getWidenedType(ScalarTy, VecSz);
69466960
6961+ // Quick detour: at this point we can say what the type of strided load would
6962+ // be if all the checks pass. Check if this type is legal for the target.
69476963 if (Sz != GroupSize) {
69486964 if (Sz % GroupSize != 0)
69496965 return false;
@@ -6960,24 +6976,21 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69606976 !TTI->isLegalStridedLoadStore(StridedLoadTy, CommonAlignment))
69616977 return false;
69626978
6963- unsigned PrevGroupStartIdx = 0;
6979+ // Continue with checking the "shape" of `SortedOffsetsFromBase`.
6980+ // Check that the strides between groups are all the same.
69646981 unsigned CurrentGroupStartIdx = GroupSize;
69656982 int64_t StrideBetweenGroups =
69666983 SortedOffsetsFromBase[GroupSize] - SortedOffsetsFromBase[0];
69676984 StrideIntVal = StrideBetweenGroups;
6968- while ( CurrentGroupStartIdx != Sz) {
6985+ for (; CurrentGroupStartIdx < Sz; CurrentGroupStartIdx += GroupSize ) {
69696986 if (SortedOffsetsFromBase[CurrentGroupStartIdx] -
6970- SortedOffsetsFromBase[PrevGroupStartIdx ] !=
6987+ SortedOffsetsFromBase[CurrentGroupStartIdx - GroupSize ] !=
69716988 StrideBetweenGroups)
6972- break;
6973- PrevGroupStartIdx = CurrentGroupStartIdx;
6974- CurrentGroupStartIdx += GroupSize;
6989+ return false;
69756990 }
6976- if (CurrentGroupStartIdx != Sz)
6977- return false;
69786991
6979- auto CheckGroup = [&](unsigned StartIdx, unsigned GroupSize0,
6980- int64_t StrideWithinGroup) -> bool {
6992+ auto CheckGroup = [&](const unsigned StartIdx, const unsigned GroupSize0,
6993+ const int64_t StrideWithinGroup) -> bool {
69816994 unsigned GroupEndIdx = StartIdx + 1;
69826995 for (; GroupEndIdx != Sz; ++GroupEndIdx) {
69836996 if (SortedOffsetsFromBase[GroupEndIdx] -
0 commit comments