@@ -6913,8 +6913,8 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69136913 const SmallVectorImpl<unsigned> &SortedIndices, const int64_t Diff, Value *Ptr0,
69146914 Value *PtrN, StridedPtrInfo &SPtrInfo) const {
69156915 const unsigned Sz = PointerOps.size();
6916- SmallVector<int64_t> SortedOffsetsFromBase;
6917- SortedOffsetsFromBase.resize(Sz);
6916+ SmallVector<int64_t> SortedOffsetsFromBase(Sz) ;
6917+ // Go through `PointerOps` in sorted order and record offsets from `Ptr0`.
69186918 for (unsigned I : seq<unsigned>(Sz)) {
69196919 Value *Ptr =
69206920 SortedIndices.empty() ? PointerOps[I] : PointerOps[SortedIndices[I]];
@@ -6923,10 +6923,24 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69236923 }
69246924 assert(SortedOffsetsFromBase.size() > 1 &&
69256925 "Trying to generate strided load for less than 2 loads");
6926- //
6927- // Find where the first group ends.
6926+ // The code below checks that `SortedOffsetsFromBase` looks as follows:
6927+ // ```
6928+ // [
6929+ // (e_{0, 0}, e_{0, 1}, ..., e_{0, GroupSize - 1}), // first group
6930+ // (e_{1, 0}, e_{1, 1}, ..., e_{1, GroupSize - 1}), // secon group
6931+ // ...
6932+ // (e_{NumGroups - 1, 0}, e_{NumGroups - 1, 1}, ..., e_{NumGroups - 1,
6933+ // GroupSize - 1}), // last group
6934+ // ]
6935+ // ```
6936+ // The distance between consecutive elements within each group should all be
6937+ // the same `StrideWithinGroup`. The distance between the first elements of
6938+ // consecutive groups should all be the same `StrideBetweenGroups`.
6939+
69286940 int64_t StrideWithinGroup =
69296941 SortedOffsetsFromBase[1] - SortedOffsetsFromBase[0];
6942+ // Determine size of the first group. Later we will check that all other
6943+ // groups have the same size.
69306944 unsigned GroupSize = 1;
69316945 for (; GroupSize != SortedOffsetsFromBase.size(); ++GroupSize) {
69326946 if (SortedOffsetsFromBase[GroupSize] -
@@ -6939,6 +6953,8 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69396953 int64_t StrideIntVal = StrideWithinGroup;
69406954 FixedVectorType *StridedLoadTy = getWidenedType(ScalarTy, VecSz);
69416955
6956+ // Quick detour: at this point we can say what the type of strided load would
6957+ // be if all the checks pass. Check if this type is legal for the target.
69426958 if (Sz != GroupSize) {
69436959 if (Sz % GroupSize != 0)
69446960 return false;
@@ -6955,24 +6971,21 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69556971 !TTI->isLegalStridedLoadStore(StridedLoadTy, CommonAlignment))
69566972 return false;
69576973
6958- unsigned PrevGroupStartIdx = 0;
6974+ // Continue with checking the "shape" of `SortedOffsetsFromBase`.
6975+ // Check that the strides between groups are all the same.
69596976 unsigned CurrentGroupStartIdx = GroupSize;
69606977 int64_t StrideBetweenGroups =
69616978 SortedOffsetsFromBase[GroupSize] - SortedOffsetsFromBase[0];
69626979 StrideIntVal = StrideBetweenGroups;
6963- while ( CurrentGroupStartIdx != Sz) {
6980+ for (; CurrentGroupStartIdx < Sz; CurrentGroupStartIdx += GroupSize ) {
69646981 if (SortedOffsetsFromBase[CurrentGroupStartIdx] -
6965- SortedOffsetsFromBase[PrevGroupStartIdx ] !=
6982+ SortedOffsetsFromBase[CurrentGroupStartIdx - GroupSize ] !=
69666983 StrideBetweenGroups)
6967- break;
6968- PrevGroupStartIdx = CurrentGroupStartIdx;
6969- CurrentGroupStartIdx += GroupSize;
6984+ return false;
69706985 }
6971- if (CurrentGroupStartIdx != Sz)
6972- return false;
69736986
6974- auto CheckGroup = [&](unsigned StartIdx, unsigned GroupSize0,
6975- int64_t StrideWithinGroup) -> bool {
6987+ auto CheckGroup = [&](const unsigned StartIdx, const unsigned GroupSize0,
6988+ const int64_t StrideWithinGroup) -> bool {
69766989 unsigned GroupEndIdx = StartIdx + 1;
69776990 for (; GroupEndIdx != Sz; ++GroupEndIdx) {
69786991 if (SortedOffsetsFromBase[GroupEndIdx] -
0 commit comments