Bug type: miscompilation
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: BoUpSLP::isGatherShuffledSingleRegisterEntry
add
Issue title: SLP Vectorizer miscompilation
Labels: miscompilation
llvm:SLPVectorizer
Reported by: aleks-tmb

During our local testing, we identified a miscompilation where the SLP Vectorizer appears to be the cause. Here is the reproducer we managed to prepare:
https://godbolt.org/z/9nePcq7Go

The issue can be demonstrated using the `lli` tool. Unfortunately, I cannot use alive2 due to unknown libcall errors, such as @llvm.vector.insert.v32i32.v16i32 not being recognized by alive2

```
$ bin/opt -passes=slp-vectorizer -mattr=+avx2 src.ll -S > tgt.ll
$ bin/lli src.ll
Result: -256
$ bin/lli tgt.ll
Result: -272
```

The pseudocode represented by the IR is
```
t = 0
for (i = 0; i < 16; i++) {
    s -= (t + i)
    t = i
}
```
```
s -= (1 + 0) + (2 + 1) + (3 + 2) + (4 + 3) + ... + (14 + 15) + (15 + 16)
s = -256
```
This indicates that the SLP Vectorizer pass produces incorrect IR.

The issue became reproducible after patch `[SLP] Match poison as instruction with the same opcode` made by @alexey-bataev 
https://github.com/llvm/llvm-project/commit/b8703369daf777706196ff914c0376c27adde3cf

I'll provide more details on how the patch affects the issue as soon as I receive them.

Comments: author: alexey-bataev
body: No related directly to this patch, reveals the bug that can be triggered even without patch. I reduced the reproducer, will commit fix soon

Fix patch:
commit 7d01a8f2b9ac28ffe73bef4b513d383d3edf34b5
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Mon Jan 20 14:22:20 2025 -0800

    [SLP]Fix vector factor for repeated node for bv
    
    When adding a node vector, when it is used already in the shuffle for
    buildvector, need to calculate vector factor from all vector, not only
    this single vector, to avoid incorrect result. Also, need to increase
    stability of the reused entries detection to avoid mismatch in cost
    estimation/codegen.
    
    Fixes #123639

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index fc3afed391a0..ad4855d90874 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -13205,9 +13205,12 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
           VTE = *MIt;
         }
       }
-      Instruction &LastBundleInst = getLastInstructionInBundle(VTE);
-      if (&LastBundleInst == TEInsertPt || !CheckOrdering(&LastBundleInst))
-        continue;
+      if (none_of(TE->CombinedEntriesWithIndices,
+                  [&](const auto &P) { return P.first == VTE->Idx; })) {
+        Instruction &LastBundleInst = getLastInstructionInBundle(VTE);
+        if (&LastBundleInst == TEInsertPt || !CheckOrdering(&LastBundleInst))
+          continue;
+      }
       VToTEs.insert(VTE);
     }
     if (VToTEs.empty())
@@ -14497,7 +14500,9 @@ public:
           break;
         }
     }
-    int VF = getVF(V1);
+    unsigned VF = 0;
+    for (Value *V : InVectors)
+      VF = std::max(VF, getVF(V));
     for (unsigned Idx = 0, Sz = CommonMask.size(); Idx < Sz; ++Idx)
       if (Mask[Idx] != PoisonMaskElem && CommonMask[Idx] == PoisonMaskElem)
         CommonMask[Idx] = Mask[Idx] + (It == InVectors.begin() ? 0 : VF);


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/X86/multi-node-reuse-in-bv.ll
commands: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -mattr=+avx2 < %s
tests: test_name: test
test_body: define i32 @main() {
entry:
  %.neg15 = sub i32 0, 0
  %0 = trunc i64 1 to i32
  %.neg.1 = sub i32 0, 0
  %.neg15.1 = sub i32 0, %0
  %.neg16.1 = add i32 %.neg.1, %.neg15.1
  %1 = add i32 %.neg16.1, %.neg15
  %2 = trunc i64 0 to i32
  %.neg.2 = sub i32 0, %0
  %.neg15.2 = sub i32 0, %2
  %.neg16.2 = add i32 %.neg.2, %.neg15.2
  %3 = add i32 %.neg16.2, %1
  %4 = trunc i64 0 to i32
  %.neg.3 = sub i32 0, %2
  %.neg15.3 = sub i32 0, %4
  %.neg16.3 = add i32 %.neg.3, %.neg15.3
  %5 = add i32 %.neg16.3, %3
  %6 = trunc i64 0 to i32
  %.neg.4 = sub i32 0, %4
  %.neg15.4 = sub i32 0, %6
  %.neg16.4 = add i32 %.neg.4, %.neg15.4
  %7 = add i32 %.neg16.4, %5
  %.neg.5 = sub i32 0, %6
  %.neg15.5 = sub i32 0, 0
  %.neg16.5 = add i32 %.neg.5, %.neg15.5
  %8 = add i32 %.neg16.5, %7
  %.neg15.6 = sub i32 0, 0
  %.neg16.6 = add i32 0, %.neg15.6
  %9 = add i32 %.neg16.6, %8
  %.neg.7 = sub i32 0, 0
  %.neg15.7 = sub i32 0, 0
  %.neg16.7 = add i32 %.neg.7, %.neg15.7
  %10 = add i32 %.neg16.7, %9
  %11 = trunc i64 0 to i32
  %.neg.8 = sub i32 0, 0
  %.neg15.8 = sub i32 0, %11
  %.neg16.8 = add i32 %.neg.8, %.neg15.8
  %12 = add i32 %.neg16.8, %10
  %13 = trunc i64 0 to i32
  %.neg.9 = sub i32 0, %11
  %.neg15.9 = sub i32 0, %13
  %.neg16.9 = add i32 %.neg.9, %.neg15.9
  %14 = add i32 %.neg16.9, %12
  %15 = trunc i64 0 to i32
  %.neg.10 = sub i32 0, %13
  %.neg15.10 = sub i32 0, %15
  %.neg16.10 = add i32 %.neg.10, %.neg15.10
  %16 = add i32 %.neg16.10, %14
  %17 = trunc i64 0 to i32
  %.neg.11 = sub i32 0, %15
  %.neg15.11 = sub i32 0, %17
  %.neg16.11 = add i32 %.neg.11, %.neg15.11
  %18 = add i32 %.neg16.11, %16
  %19 = trunc i64 0 to i32
  %.neg.12 = sub i32 0, %17
  %.neg15.12 = sub i32 0, %19
  %.neg16.12 = add i32 %.neg.12, %.neg15.12
  %20 = add i32 %.neg16.12, %18
  %.neg.13 = sub i32 0, %19
  %.neg15.13 = sub i32 0, 0
  %.neg16.13 = add i32 %.neg.13, %.neg15.13
  %21 = add i32 %.neg16.13, %20
  %.neg.14 = sub i32 0, 0
  %.neg15.14 = sub i32 0, 0
  %.neg16.14 = add i32 %.neg.14, %.neg15.14
  %22 = add i32 %.neg16.14, %21
  %.neg.15 = sub i32 0, 0
  %.neg15.15 = sub i32 0, 0
  %.neg16.15 = add i32 %.neg.15, %.neg15.15
  %23 = add i32 %.neg16.15, %22
  %.neg.16 = sub i32 0, 0
  %.neg15.16 = sub i32 0, 0
  %.neg16.16 = add i32 %.neg.16, %.neg15.16
  %24 = add i32 %.neg16.16, %23
  %res = xor i32 %24, -2
  ret i32 %res
}