Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: computeExtractCost
Issue title: SLP Vectorizer Options trigger Assertion in cost computation on `s390x`
Labels: llvm:SLPVectorizer
crash
Reported by: dominik-steenken

While running experiments with `csmith`, i ran into the following example (already reduced with `cvise`):
```C
static int c[][10];
short d;
long *e;
long f;
int g, k;
char h, i;
static int j[3];
void l();
static int *m() {
  short *n = &d;
  d = 0;
  for (; d <= 2;)
    if (*n)
      ;
    else
      return j;
  return &g;
}
void p() { l(); }
void l() {
  int *q;
  h = 0;
  for (; h <= 6; h++) {
    int **r = &q;
    *e = 4073709551615;
    *r = m();
    k = 0;
    for (; k <= 6; k++) {
      i = 2;
      for (; i <= 6; i++)
        **r |= c[k][h] ^= f;
    }
  }
}
```
 When compiling this with the options
```
  -O3 \
  -S \
  -w \
  -c \
  -o a.out \
  --target=s390x-ibm-linux \
  -march=z13 \
  -mllvm -slp-max-reg-size=256 \
  -mllvm -slp-vectorize-hor-store \
  -mllvm -slp-vectorize-non-power-of-2 \
  -mllvm -enable-tbaa=false \
```
The assertion `(Idx + EltsPerVector) <= BaseVF && "SK_ExtractSubvector index out of range"` fails in `llvm::slpvectorizer::BoUpSLP::ShuffleCostEstimator::computeExtractCost`. This does not seem to be an issue on X86.

[repro.tar.gz](https://github.com/user-attachments/files/20672338/repro.tar.gz)


Fix patch:
commit 0108a5908cab5e418c683ef9b6e1810755344b5e
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Tue Jun 17 07:55:52 2025 -0700

    [SLP]Fix a crash on an subvector size calculation for non-power-of-2 vector
    
    Patch fixes cost estimation for the extractelements from non-power-of-2
    vectors, defined as subvector extracts. In this case the subvector size
    might be not adjusted to a whole register size, need to get the minimum
    between whole vector size and the actual difference to prevent compiler
    crash.
    
    Fixes #143513

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index d811e9d77d18..4551a365a696 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -12085,7 +12085,8 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
     // FIXME: this must be moved to TTI for better estimation.
     unsigned EltsPerVector = getPartNumElems(VL.size(), NumParts);
     auto CheckPerRegistersShuffle = [&](MutableArrayRef<int> Mask,
-                                        SmallVectorImpl<unsigned> &Indices)
+                                        SmallVectorImpl<unsigned> &Indices,
+                                        SmallVectorImpl<unsigned> &SubVecSizes)
         -> std::optional<TTI::ShuffleKind> {
       if (NumElts <= EltsPerVector)
         return std::nullopt;
@@ -12130,7 +12131,9 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
                       return std::min(S, I);
                     }),
                 EltsPerVector);
-            Indices.push_back(OffsetReg1 % NumElts);
+            unsigned Index = OffsetReg1 % NumElts;
+            Indices.push_back(Index);
+            SubVecSizes.push_back(std::min(NumElts - Index, EltsPerVector));
           }
           Idx = I - OffsetReg1;
         }
@@ -12152,8 +12155,9 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
       SmallVector<int> SubMask(EltsPerVector, PoisonMaskElem);
       copy(MaskSlice, SubMask.begin());
       SmallVector<unsigned, 2> Indices;
+      SmallVector<unsigned, 2> SubVecSizes;
       std::optional<TTI::ShuffleKind> RegShuffleKind =
-          CheckPerRegistersShuffle(SubMask, Indices);
+          CheckPerRegistersShuffle(SubMask, Indices, SubVecSizes);
       if (!RegShuffleKind) {
         if (*ShuffleKinds[Part] != TTI::SK_PermuteSingleSrc ||
             !ShuffleVectorInst::isIdentityMask(
@@ -12171,12 +12175,12 @@ class BoUpSLP::ShuffleCostEstimator : public BaseShuffleAnalysis {
       }
       const unsigned BaseVF = getFullVectorNumberOfElements(
           *R.TTI, VL.front()->getType(), alignTo(NumElts, EltsPerVector));
-      for (unsigned Idx : Indices) {
-        assert((Idx + EltsPerVector) <= BaseVF &&
+      for (const auto [Idx, SubVecSize] : zip(Indices, SubVecSizes)) {
+        assert((Idx + SubVecSize) <= BaseVF &&
                "SK_ExtractSubvector index out of range");
         Cost += ::getShuffleCost(TTI, TTI::SK_ExtractSubvector,
                                  getWidenedType(ScalarTy, BaseVF), {}, CostKind,
-                                 Idx, getWidenedType(ScalarTy, EltsPerVector));
+                                 Idx, getWidenedType(ScalarTy, SubVecSize));
       }
       // Second attempt to check, if just a permute is better estimated than
       // subvector extract.


Regression tests:
file: llvm/test/Transforms/PhaseOrdering/X86/hadd.ll
commands: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64
opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v2
opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v3
opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v4
opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64
opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64-v2
opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64-v3
opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64-v4
tests: test_name: add_v16i16_0123u56789uBCDEF
test_body: define <16 x i16> @add_v16i16_0123u56789uBCDEF(<16 x i16> %a, <16 x i16> %b) {
  %a0 = extractelement <16 x i16> %a, i32 0
  %a1 = extractelement <16 x i16> %a, i32 1
  %a2 = extractelement <16 x i16> %a, i32 2
  %a3 = extractelement <16 x i16> %a, i32 3
  %a4 = extractelement <16 x i16> %a, i32 4
  %a5 = extractelement <16 x i16> %a, i32 5
  %a6 = extractelement <16 x i16> %a, i32 6
  %a7 = extractelement <16 x i16> %a, i32 7
  %a8 = extractelement <16 x i16> %a, i32 8
  %a9 = extractelement <16 x i16> %a, i32 9
  %aA = extractelement <16 x i16> %a, i32 10
  %aB = extractelement <16 x i16> %a, i32 11
  %aC = extractelement <16 x i16> %a, i32 12
  %aD = extractelement <16 x i16> %a, i32 13
  %aE = extractelement <16 x i16> %a, i32 14
  %aF = extractelement <16 x i16> %a, i32 15
  %a01 = add i16 %a0, %a1
  %a23 = add i16 %a2, %a3
  %a45 = add i16 %a4, %a5
  %a67 = add i16 %a6, %a7
  %a89 = add i16 %a8, %a9
  %aAB = add i16 %aA, %aB
  %aCD = add i16 %aC, %aD
  %aEF = add i16 %aE, %aF
  %b0 = extractelement <16 x i16> %b, i32 0
  %b1 = extractelement <16 x i16> %b, i32 1
  %b2 = extractelement <16 x i16> %b, i32 2
  %b3 = extractelement <16 x i16> %b, i32 3
  %b4 = extractelement <16 x i16> %b, i32 4
  %b5 = extractelement <16 x i16> %b, i32 5
  %b6 = extractelement <16 x i16> %b, i32 6
  %b7 = extractelement <16 x i16> %b, i32 7
  %b8 = extractelement <16 x i16> %b, i32 8
  %b9 = extractelement <16 x i16> %b, i32 9
  %bA = extractelement <16 x i16> %b, i32 10
  %bB = extractelement <16 x i16> %b, i32 11
  %bC = extractelement <16 x i16> %b, i32 12
  %bD = extractelement <16 x i16> %b, i32 13
  %bE = extractelement <16 x i16> %b, i32 14
  %bF = extractelement <16 x i16> %b, i32 15
  %b01 = add i16 %b0, %b1
  %b23 = add i16 %b2, %b3
  %b45 = add i16 %b4, %b5
  %b67 = add i16 %b6, %b7
  %b89 = add i16 %b8, %b9
  %bAB = add i16 %bA, %bB
  %bCD = add i16 %bC, %bD
  %bEF = add i16 %bE, %bF
  %hadd0 = insertelement <16 x i16> poison, i16 %a01, i32 0
  %hadd1 = insertelement <16 x i16> %hadd0, i16 %a23, i32 1
  %hadd2 = insertelement <16 x i16> %hadd1, i16 %a45, i32 2
  %hadd3 = insertelement <16 x i16> %hadd2, i16 %a67, i32 3
  %hadd4 = insertelement <16 x i16> %hadd3, i16 %b01, i32 4
  %hadd5 = insertelement <16 x i16> %hadd4, i16 %b23, i32 5
  %hadd6 = insertelement <16 x i16> %hadd5, i16 %b45, i32 6
  %hadd7 = insertelement <16 x i16> %hadd6, i16 %b67, i32 7
  %hadd8 = insertelement <16 x i16> %hadd7, i16 %a89, i32 8
  %hadd9 = insertelement <16 x i16> %hadd8, i16 %aAB, i32 9
  %haddA = insertelement <16 x i16> %hadd9, i16 %aCD, i32 10
  %haddB = insertelement <16 x i16> %haddA, i16 %aEF, i32 11
  %haddC = insertelement <16 x i16> %haddB, i16 %b89, i32 12
  %haddD = insertelement <16 x i16> %haddC, i16 %bAB, i32 13
  %haddE = insertelement <16 x i16> %haddD, i16 %bCD, i32 14
  %haddF = insertelement <16 x i16> %haddE, i16 %bEF, i32 15
  %result = shufflevector <16 x i16> %haddF, <16 x i16> %a, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 5, i32 6, i32 7, i32 8, i32 9, i32 poison, i32 11, i32 12, i32 13, i32 14, i32 15>
  ret <16 x i16> %result
}

test_name: add_v16i16_0123456789ABCDEF
test_body: define <16 x i16> @add_v16i16_0123456789ABCDEF(<16 x i16> %a, <16 x i16> %b) {
  %a0 = extractelement <16 x i16> %a, i32 0
  %a1 = extractelement <16 x i16> %a, i32 1
  %a2 = extractelement <16 x i16> %a, i32 2
  %a3 = extractelement <16 x i16> %a, i32 3
  %a4 = extractelement <16 x i16> %a, i32 4
  %a5 = extractelement <16 x i16> %a, i32 5
  %a6 = extractelement <16 x i16> %a, i32 6
  %a7 = extractelement <16 x i16> %a, i32 7
  %a8 = extractelement <16 x i16> %a, i32 8
  %a9 = extractelement <16 x i16> %a, i32 9
  %aA = extractelement <16 x i16> %a, i32 10
  %aB = extractelement <16 x i16> %a, i32 11
  %aC = extractelement <16 x i16> %a, i32 12
  %aD = extractelement <16 x i16> %a, i32 13
  %aE = extractelement <16 x i16> %a, i32 14
  %aF = extractelement <16 x i16> %a, i32 15
  %a01 = add i16 %a0, %a1
  %a23 = add i16 %a2, %a3
  %a45 = add i16 %a4, %a5
  %a67 = add i16 %a6, %a7
  %a89 = add i16 %a8, %a9
  %aAB = add i16 %aA, %aB
  %aCD = add i16 %aC, %aD
  %aEF = add i16 %aE, %aF
  %b0 = extractelement <16 x i16> %b, i32 0
  %b1 = extractelement <16 x i16> %b, i32 1
  %b2 = extractelement <16 x i16> %b, i32 2
  %b3 = extractelement <16 x i16> %b, i32 3
  %b4 = extractelement <16 x i16> %b, i32 4
  %b5 = extractelement <16 x i16> %b, i32 5
  %b6 = extractelement <16 x i16> %b, i32 6
  %b7 = extractelement <16 x i16> %b, i32 7
  %b8 = extractelement <16 x i16> %b, i32 8
  %b9 = extractelement <16 x i16> %b, i32 9
  %bA = extractelement <16 x i16> %b, i32 10
  %bB = extractelement <16 x i16> %b, i32 11
  %bC = extractelement <16 x i16> %b, i32 12
  %bD = extractelement <16 x i16> %b, i32 13
  %bE = extractelement <16 x i16> %b, i32 14
  %bF = extractelement <16 x i16> %b, i32 15
  %b01 = add i16 %b0, %b1
  %b23 = add i16 %b2, %b3
  %b45 = add i16 %b4, %b5
  %b67 = add i16 %b6, %b7
  %b89 = add i16 %b8, %b9
  %bAB = add i16 %bA, %bB
  %bCD = add i16 %bC, %bD
  %bEF = add i16 %bE, %bF
  %hadd0 = insertelement <16 x i16> poison, i16 %a01, i32 0
  %hadd1 = insertelement <16 x i16> %hadd0, i16 %a23, i32 1
  %hadd2 = insertelement <16 x i16> %hadd1, i16 %a45, i32 2
  %hadd3 = insertelement <16 x i16> %hadd2, i16 %a67, i32 3
  %hadd4 = insertelement <16 x i16> %hadd3, i16 %b01, i32 4
  %hadd5 = insertelement <16 x i16> %hadd4, i16 %b23, i32 5
  %hadd6 = insertelement <16 x i16> %hadd5, i16 %b45, i32 6
  %hadd7 = insertelement <16 x i16> %hadd6, i16 %b67, i32 7
  %hadd8 = insertelement <16 x i16> %hadd7, i16 %a89, i32 8
  %hadd9 = insertelement <16 x i16> %hadd8, i16 %aAB, i32 9
  %haddA = insertelement <16 x i16> %hadd9, i16 %aCD, i32 10
  %haddB = insertelement <16 x i16> %haddA, i16 %aEF, i32 11
  %haddC = insertelement <16 x i16> %haddB, i16 %b89, i32 12
  %haddD = insertelement <16 x i16> %haddC, i16 %bAB, i32 13
  %haddE = insertelement <16 x i16> %haddD, i16 %bCD, i32 14
  %haddF = insertelement <16 x i16> %haddE, i16 %bEF, i32 15
  %result = shufflevector <16 x i16> %haddF, <16 x i16> %a, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
  ret <16 x i16> %result
}

file: llvm/test/Transforms/PhaseOrdering/X86/hsub.ll
commands: opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64
opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v2
opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v3
opt < %s -O3 -S -mtriple=x86_64-- -mcpu=x86-64-v4
opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64
opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64-v2
opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64-v3
opt < %s -passes="default<O3>" -S -mtriple=x86_64-- -mcpu=x86-64-v4
tests: test_name: sub_v16i16_0123456789ABCDEF
test_body: define <16 x i16> @sub_v16i16_0123456789ABCDEF(<16 x i16> %a, <16 x i16> %b) {
  %a0 = extractelement <16 x i16> %a, i32 0
  %a1 = extractelement <16 x i16> %a, i32 1
  %a2 = extractelement <16 x i16> %a, i32 2
  %a3 = extractelement <16 x i16> %a, i32 3
  %a4 = extractelement <16 x i16> %a, i32 4
  %a5 = extractelement <16 x i16> %a, i32 5
  %a6 = extractelement <16 x i16> %a, i32 6
  %a7 = extractelement <16 x i16> %a, i32 7
  %a8 = extractelement <16 x i16> %a, i32 8
  %a9 = extractelement <16 x i16> %a, i32 9
  %aA = extractelement <16 x i16> %a, i32 10
  %aB = extractelement <16 x i16> %a, i32 11
  %aC = extractelement <16 x i16> %a, i32 12
  %aD = extractelement <16 x i16> %a, i32 13
  %aE = extractelement <16 x i16> %a, i32 14
  %aF = extractelement <16 x i16> %a, i32 15
  %a01 = sub i16 %a0, %a1
  %a23 = sub i16 %a2, %a3
  %a45 = sub i16 %a4, %a5
  %a67 = sub i16 %a6, %a7
  %a89 = sub i16 %a8, %a9
  %aAB = sub i16 %aA, %aB
  %aCD = sub i16 %aC, %aD
  %aEF = sub i16 %aE, %aF
  %b0 = extractelement <16 x i16> %b, i32 0
  %b1 = extractelement <16 x i16> %b, i32 1
  %b2 = extractelement <16 x i16> %b, i32 2
  %b3 = extractelement <16 x i16> %b, i32 3
  %b4 = extractelement <16 x i16> %b, i32 4
  %b5 = extractelement <16 x i16> %b, i32 5
  %b6 = extractelement <16 x i16> %b, i32 6
  %b7 = extractelement <16 x i16> %b, i32 7
  %b8 = extractelement <16 x i16> %b, i32 8
  %b9 = extractelement <16 x i16> %b, i32 9
  %bA = extractelement <16 x i16> %b, i32 10
  %bB = extractelement <16 x i16> %b, i32 11
  %bC = extractelement <16 x i16> %b, i32 12
  %bD = extractelement <16 x i16> %b, i32 13
  %bE = extractelement <16 x i16> %b, i32 14
  %bF = extractelement <16 x i16> %b, i32 15
  %b01 = sub i16 %b0, %b1
  %b23 = sub i16 %b2, %b3
  %b45 = sub i16 %b4, %b5
  %b67 = sub i16 %b6, %b7
  %b89 = sub i16 %b8, %b9
  %bAB = sub i16 %bA, %bB
  %bCD = sub i16 %bC, %bD
  %bEF = sub i16 %bE, %bF
  %hsub0 = insertelement <16 x i16> poison, i16 %a01, i32 0
  %hsub1 = insertelement <16 x i16> %hsub0, i16 %a23, i32 1
  %hsub2 = insertelement <16 x i16> %hsub1, i16 %a45, i32 2
  %hsub3 = insertelement <16 x i16> %hsub2, i16 %a67, i32 3
  %hsub4 = insertelement <16 x i16> %hsub3, i16 %b01, i32 4
  %hsub5 = insertelement <16 x i16> %hsub4, i16 %b23, i32 5
  %hsub6 = insertelement <16 x i16> %hsub5, i16 %b45, i32 6
  %hsub7 = insertelement <16 x i16> %hsub6, i16 %b67, i32 7
  %hsub8 = insertelement <16 x i16> %hsub7, i16 %a89, i32 8
  %hsub9 = insertelement <16 x i16> %hsub8, i16 %aAB, i32 9
  %hsubA = insertelement <16 x i16> %hsub9, i16 %aCD, i32 10
  %hsubB = insertelement <16 x i16> %hsubA, i16 %aEF, i32 11
  %hsubC = insertelement <16 x i16> %hsubB, i16 %b89, i32 12
  %hsubD = insertelement <16 x i16> %hsubC, i16 %bAB, i32 13
  %hsubE = insertelement <16 x i16> %hsubD, i16 %bCD, i32 14
  %hsubF = insertelement <16 x i16> %hsubE, i16 %bEF, i32 15
  %result = shufflevector <16 x i16> %hsubF, <16 x i16> %a, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
  ret <16 x i16> %result
}

test_name: sub_v16i16_0123u56789uBCDEF
test_body: define <16 x i16> @sub_v16i16_0123u56789uBCDEF(<16 x i16> %a, <16 x i16> %b) {
  %a0 = extractelement <16 x i16> %a, i32 0
  %a1 = extractelement <16 x i16> %a, i32 1
  %a2 = extractelement <16 x i16> %a, i32 2
  %a3 = extractelement <16 x i16> %a, i32 3
  %a4 = extractelement <16 x i16> %a, i32 4
  %a5 = extractelement <16 x i16> %a, i32 5
  %a6 = extractelement <16 x i16> %a, i32 6
  %a7 = extractelement <16 x i16> %a, i32 7
  %a8 = extractelement <16 x i16> %a, i32 8
  %a9 = extractelement <16 x i16> %a, i32 9
  %aA = extractelement <16 x i16> %a, i32 10
  %aB = extractelement <16 x i16> %a, i32 11
  %aC = extractelement <16 x i16> %a, i32 12
  %aD = extractelement <16 x i16> %a, i32 13
  %aE = extractelement <16 x i16> %a, i32 14
  %aF = extractelement <16 x i16> %a, i32 15
  %a01 = sub i16 %a0, %a1
  %a23 = sub i16 %a2, %a3
  %a45 = sub i16 %a4, %a5
  %a67 = sub i16 %a6, %a7
  %a89 = sub i16 %a8, %a9
  %aAB = sub i16 %aA, %aB
  %aCD = sub i16 %aC, %aD
  %aEF = sub i16 %aE, %aF
  %b0 = extractelement <16 x i16> %b, i32 0
  %b1 = extractelement <16 x i16> %b, i32 1
  %b2 = extractelement <16 x i16> %b, i32 2
  %b3 = extractelement <16 x i16> %b, i32 3
  %b4 = extractelement <16 x i16> %b, i32 4
  %b5 = extractelement <16 x i16> %b, i32 5
  %b6 = extractelement <16 x i16> %b, i32 6
  %b7 = extractelement <16 x i16> %b, i32 7
  %b8 = extractelement <16 x i16> %b, i32 8
  %b9 = extractelement <16 x i16> %b, i32 9
  %bA = extractelement <16 x i16> %b, i32 10
  %bB = extractelement <16 x i16> %b, i32 11
  %bC = extractelement <16 x i16> %b, i32 12
  %bD = extractelement <16 x i16> %b, i32 13
  %bE = extractelement <16 x i16> %b, i32 14
  %bF = extractelement <16 x i16> %b, i32 15
  %b01 = sub i16 %b0, %b1
  %b23 = sub i16 %b2, %b3
  %b45 = sub i16 %b4, %b5
  %b67 = sub i16 %b6, %b7
  %b89 = sub i16 %b8, %b9
  %bAB = sub i16 %bA, %bB
  %bCD = sub i16 %bC, %bD
  %bEF = sub i16 %bE, %bF
  %hsub0 = insertelement <16 x i16> poison, i16 %a01, i32 0
  %hsub1 = insertelement <16 x i16> %hsub0, i16 %a23, i32 1
  %hsub2 = insertelement <16 x i16> %hsub1, i16 %a45, i32 2
  %hsub3 = insertelement <16 x i16> %hsub2, i16 %a67, i32 3
  %hsub4 = insertelement <16 x i16> %hsub3, i16 %b01, i32 4
  %hsub5 = insertelement <16 x i16> %hsub4, i16 %b23, i32 5
  %hsub6 = insertelement <16 x i16> %hsub5, i16 %b45, i32 6
  %hsub7 = insertelement <16 x i16> %hsub6, i16 %b67, i32 7
  %hsub8 = insertelement <16 x i16> %hsub7, i16 %a89, i32 8
  %hsub9 = insertelement <16 x i16> %hsub8, i16 %aAB, i32 9
  %hsubA = insertelement <16 x i16> %hsub9, i16 %aCD, i32 10
  %hsubB = insertelement <16 x i16> %hsubA, i16 %aEF, i32 11
  %hsubC = insertelement <16 x i16> %hsubB, i16 %b89, i32 12
  %hsubD = insertelement <16 x i16> %hsubC, i16 %bAB, i32 13
  %hsubE = insertelement <16 x i16> %hsubD, i16 %bCD, i32 14
  %hsubF = insertelement <16 x i16> %hsubE, i16 %bEF, i32 15
  %result = shufflevector <16 x i16> %hsubF, <16 x i16> %a, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 5, i32 6, i32 7, i32 8, i32 9, i32 poison, i32 11, i32 12, i32 13, i32 14, i32 15>
  ret <16 x i16> %result
}

file: llvm/test/Transforms/SLPVectorizer/SystemZ/non-power-2-subvector-extract.ll
commands: opt -S --passes=slp-vectorizer -mtriple=s390x-ibm-linux -mcpu=z13 -slp-max-reg-size=256 -slp-vectorize-hor-store -slp-vectorize-non-power-of-2 < %s
tests: test_name: <module>
test_body: 
@c = external global [1 x [10 x i32]]
@j.0 = external global i32

define void @p() {
;
entry:
  %arrayidx12.promoted.5.i = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 200), align 4
  %conv14.5.i = xor i32 %arrayidx12.promoted.5.i, 1
  store i32 %conv14.5.i, ptr getelementptr inbounds nuw (i8, ptr @c, i64 200), align 4
  %arrayidx12.promoted.5.i.1 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 204), align 4
  %conv14.5.i.1 = xor i32 %arrayidx12.promoted.5.i.1, 1
  store i32 %conv14.5.i.1, ptr getelementptr inbounds nuw (i8, ptr @c, i64 204), align 4
  %arrayidx12.promoted.5.i.2 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 208), align 4
  %conv14.5.i.2 = xor i32 %arrayidx12.promoted.5.i.2, 1
  store i32 %conv14.5.i.2, ptr getelementptr inbounds nuw (i8, ptr @c, i64 208), align 4
  %arrayidx12.promoted.1.i.3 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 52), align 4
  %conv14.1.i.3 = xor i32 %arrayidx12.promoted.1.i.3, 1
  store i32 %conv14.1.i.3, ptr getelementptr inbounds nuw (i8, ptr @c, i64 52), align 4
  %arrayidx12.promoted.5.i.3 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 212), align 4
  %conv14.5.i.3 = xor i32 %arrayidx12.promoted.5.i.3, 1
  store i32 %conv14.5.i.3, ptr getelementptr inbounds nuw (i8, ptr @c, i64 212), align 4
  %arrayidx12.promoted.6.i.3 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 252), align 4
  %conv14.6.i.3 = xor i32 %arrayidx12.promoted.6.i.3, 1
  %or.1.5.i.3 = or i32 %arrayidx12.promoted.1.i.3, %arrayidx12.promoted.5.i.3
  store i32 %conv14.6.i.3, ptr getelementptr inbounds nuw (i8, ptr @c, i64 252), align 4
  store i32 %or.1.5.i.3, ptr @j.0, align 4
  %arrayidx12.promoted.1.i.4 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 56), align 4
  %conv14.1.i.4 = xor i32 %arrayidx12.promoted.1.i.4, 1
  store i32 %conv14.1.i.4, ptr getelementptr inbounds nuw (i8, ptr @c, i64 56), align 4
  %arrayidx12.promoted.5.i.4 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 216), align 4
  %conv14.5.i.4 = xor i32 %arrayidx12.promoted.5.i.4, 1
  store i32 %conv14.5.i.4, ptr getelementptr inbounds nuw (i8, ptr @c, i64 216), align 4
  %arrayidx12.promoted.6.i.4 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 256), align 4
  %conv14.6.i.4 = xor i32 %arrayidx12.promoted.6.i.4, 1
  store i32 %conv14.6.i.4, ptr getelementptr inbounds nuw (i8, ptr @c, i64 256), align 4
  %arrayidx12.promoted.1.i.5 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 60), align 4
  %conv14.1.i.5 = xor i32 %arrayidx12.promoted.1.i.5, 1
  store i32 %conv14.1.i.5, ptr getelementptr inbounds nuw (i8, ptr @c, i64 60), align 4
  %arrayidx12.promoted.5.i.5 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 220), align 4
  %conv14.5.i.5 = xor i32 %arrayidx12.promoted.5.i.5, 1
  store i32 %conv14.5.i.5, ptr getelementptr inbounds nuw (i8, ptr @c, i64 220), align 4
  %arrayidx12.promoted.6.i.5 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 260), align 4
  %conv14.6.i.5 = xor i32 %arrayidx12.promoted.6.i.5, 1
  %0 = or i32 %arrayidx12.promoted.6.i.4, %arrayidx12.promoted.1.i.5
  %or.1.5.i.5 = or i32 %0, %arrayidx12.promoted.5.i.5
  %or.1.6.i.5 = or i32 %or.1.5.i.5, %arrayidx12.promoted.6.i.5
  store i32 %conv14.6.i.5, ptr getelementptr inbounds nuw (i8, ptr @c, i64 260), align 4
  store i32 %or.1.6.i.5, ptr @j.0, align 4
  %arrayidx12.promoted.1.i.6 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 64), align 4
  %conv14.1.i.6 = xor i32 %arrayidx12.promoted.1.i.6, 1
  store i32 %conv14.1.i.6, ptr getelementptr inbounds nuw (i8, ptr @c, i64 64), align 4
  %arrayidx12.promoted.5.i.6 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 224), align 4
  %conv14.5.i.6 = xor i32 %arrayidx12.promoted.5.i.6, 1
  store i32 %conv14.5.i.6, ptr getelementptr inbounds nuw (i8, ptr @c, i64 224), align 4
  %arrayidx12.promoted.6.i.6 = load i32, ptr getelementptr inbounds nuw (i8, ptr @c, i64 264), align 4
  %conv14.6.i.6 = xor i32 %arrayidx12.promoted.6.i.6, 1
  store i32 %conv14.6.i.6, ptr getelementptr inbounds nuw (i8, ptr @c, i64 264), align 4
  ret void
}