@@ -6923,8 +6923,8 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69236923 const SmallVectorImpl<unsigned> &SortedIndices, const int64_t Diff, Value *Ptr0,
69246924 Value *PtrN, StridedPtrInfo &SPtrInfo) const {
69256925 const unsigned Sz = PointerOps.size();
6926- SmallVector<int64_t> SortedOffsetsFromBase;
6927- SortedOffsetsFromBase.resize(Sz);
6926+ SmallVector<int64_t> SortedOffsetsFromBase(Sz) ;
6927+ // Go through `PointerOps` in sorted order and record offsets from `Ptr0`.
69286928 for (unsigned I : seq<unsigned>(Sz)) {
69296929 Value *Ptr =
69306930 SortedIndices.empty() ? PointerOps[I] : PointerOps[SortedIndices[I]];
@@ -6933,10 +6933,24 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69336933 }
69346934 assert(SortedOffsetsFromBase.size() > 1 &&
69356935 "Trying to generate strided load for less than 2 loads");
6936- //
6937- // Find where the first group ends.
6936+ // The code below checks that `SortedOffsetsFromBase` looks as follows:
6937+ // ```
6938+ // [
6939+ // (e_{0, 0}, e_{0, 1}, ..., e_{0, GroupSize - 1}), // first group
6940+ // (e_{1, 0}, e_{1, 1}, ..., e_{1, GroupSize - 1}), // secon group
6941+ // ...
6942+ // (e_{NumGroups - 1, 0}, e_{NumGroups - 1, 1}, ..., e_{NumGroups - 1,
6943+ // GroupSize - 1}), // last group
6944+ // ]
6945+ // ```
6946+ // The distance between consecutive elements within each group should all be
6947+ // the same `StrideWithinGroup`. The distance between the first elements of
6948+ // consecutive groups should all be the same `StrideBetweenGroups`.
6949+
69386950 int64_t StrideWithinGroup =
69396951 SortedOffsetsFromBase[1] - SortedOffsetsFromBase[0];
6952+ // Determine size of the first group. Later we will check that all other
6953+ // groups have the same size.
69406954 unsigned GroupSize = 1;
69416955 for (; GroupSize != SortedOffsetsFromBase.size(); ++GroupSize) {
69426956 if (SortedOffsetsFromBase[GroupSize] -
@@ -6949,6 +6963,8 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69496963 int64_t StrideIntVal = StrideWithinGroup;
69506964 FixedVectorType *StridedLoadTy = getWidenedType(ScalarTy, VecSz);
69516965
6966+ // Quick detour: at this point we can say what the type of strided load would
6967+ // be if all the checks pass. Check if this type is legal for the target.
69526968 bool NeedsWidening = Sz != GroupSize;
69536969 if (NeedsWidening) {
69546970 if (Sz % GroupSize != 0)
@@ -6968,24 +6984,21 @@ bool BoUpSLP::analyzeConstantStrideCandidate(
69686984 return false;
69696985
69706986 if (NeedsWidening) {
6971- unsigned PrevGroupStartIdx = 0;
6987+ // Continue with checking the "shape" of `SortedOffsetsFromBase`.
6988+ // Check that the strides between groups are all the same.
69726989 unsigned CurrentGroupStartIdx = GroupSize;
69736990 int64_t StrideBetweenGroups =
69746991 SortedOffsetsFromBase[GroupSize] - SortedOffsetsFromBase[0];
69756992 StrideIntVal = StrideBetweenGroups;
6976- while ( CurrentGroupStartIdx != Sz) {
6993+ for (; CurrentGroupStartIdx < Sz; CurrentGroupStartIdx += GroupSize ) {
69776994 if (SortedOffsetsFromBase[CurrentGroupStartIdx] -
6978- SortedOffsetsFromBase[PrevGroupStartIdx ] !=
6995+ SortedOffsetsFromBase[CurrentGroupStartIdx - GroupSize ] !=
69796996 StrideBetweenGroups)
6980- break;
6981- PrevGroupStartIdx = CurrentGroupStartIdx;
6982- CurrentGroupStartIdx += GroupSize;
6997+ return false;
69836998 }
6984- if (CurrentGroupStartIdx != Sz)
6985- return false;
69866999
6987- auto CheckGroup = [&](unsigned StartIdx, unsigned GroupSize0,
6988- int64_t StrideWithinGroup) -> bool {
7000+ auto CheckGroup = [&](const unsigned StartIdx, const unsigned GroupSize0,
7001+ const int64_t StrideWithinGroup) -> bool {
69897002 unsigned GroupEndIdx = StartIdx + 1;
69907003 for (; GroupEndIdx != Sz; ++GroupEndIdx) {
69917004 if (SortedOffsetsFromBase[GroupEndIdx] -
0 commit comments