Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: BoUpSLP::isGatherShuffledSingleRegisterEntry
Issue title: [SLPVectorizer] Instruction does not dominate all uses! ...LLVM ERROR: Broken module found, compilation aborted!
Labels: llvm:SLPVectorizer
crash
Reported by: TatyanaDoubts

To reproduce run opt with the test below with -passes=slp-vectorizer -slp-threshold=-99999:
```
; ModuleID = './reduced.ll'
source_filename = "./reduced.ll"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128-ni:1-p2:32:8:8:32-ni:2"
target triple = "x86_64-unknown-linux-gnu"

define void @wombat(i32 %arg) #0 gc "statepoint-example" {
bb:
  br label %bb1

bb1:                                              ; preds = %bb
  br i1 false, label %bb2, label %bb5

bb2:                                              ; preds = %bb4, %bb1
  %phi = phi i32 [ %or, %bb4 ], [ 0, %bb1 ]
  %phi3 = phi i32 [ %sub, %bb4 ], [ 0, %bb1 ]
  %or = or i32 %phi, 1
  %and = and i32 0, %phi
  %sub = sub i32 %phi3, %arg
  br label %bb4

bb4:                                              ; preds = %bb2
  br i1 false, label %bb2, label %bb5

bb5:                                              ; preds = %bb4, %bb1
  %phi6 = phi i32 [ 0, %bb1 ], [ %and, %bb4 ]
  %phi7 = phi i32 [ 0, %bb1 ], [ %sub, %bb4 ]
  ret void
}

attributes #0 = { "target-features"="+prfchw,-cldemote,+avx,+aes,+sahf,+pclmul,-xop,+crc32,-amx-fp8,+xsaves,-avx512fp16,-usermsr,-sm4,-egpr,+sse4.1,-avx512ifma,+xsave,+sse4.2,-tsxldtrk,-sm3,-ptwrite,-widekl,-movrs,+invpcid,+64bit,+xsavec,-avx10.1-512,-avx512vpopcntdq,+cmov,-avx512vp2intersect,+avx512cd,+movbe,-avxvnniint8,-ccmp,-amx-int8,-kl,-avx10.1-256,+evex512,-avxvnni,+rtm,+adx,+avx2,-hreset,-movdiri,-serialize,-sha512,-vpclmulqdq,+avx512vl,-uintr,-cf,+clflushopt,-raoint,-cmpccxadd,+bmi,-amx-tile,+sse,-avx10.2-256,-gfni,-avxvnniint16,-amx-fp16,-zu,-ndd,+xsaveopt,+rdrnd,+avx512f,-amx-bf16,-avx512bf16,-avx512vnni,-push2pop2,+cx8,+avx512bw,+sse3,+pku,-nf,-amx-tf32,-amx-avx512,+fsgsbase,-clzero,-mwaitx,-lwp,+lzcnt,-sha,-movdir64b,-ppx,-wbnoinvd,-enqcmd,-amx-transpose,-avx10.2-512,-avxneconvert,-tbm,-pconfig,-amx-complex,+ssse3,+cx16,+bmi2,+fma,+popcnt,-avxifma,+f16c,-avx512bitalg,-rdpru,+clwb,+mmx,+sse2,+rdseed,-avx512vbmi2,-prefetchi,-amx-movrs,-rdpid,-fma4,-avx512vbmi,-shstk,-vaes,-waitpkg,-sgx,+fxsr,+avx512dq,-sse4a,-avx512f" }
```
Reproducer: https://godbolt.org/z/Pfa9ca1o9



Stack dump:
```
Instruction does not dominate all uses!
  %5 = insertelement <2 x i32> <i32 poison, i32 0>, i32 %arg, i32 0
  %1 = shufflevector <2 x i32> %5, <2 x i32> <i32 poison, i32 1>, <2 x i32> <i32 0, i32 3>
LLVM ERROR: Broken module found, compilation aborted!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/opt -o /app/output.s -S -passes=slp-vectorizer -slp-threshold=-99999 <source>
1.	Running pass "verify" on module "<source>"
 #0 0x0000000005480a38 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5480a38)
 #1 0x000000000547e3f4 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #2 0x000072fce1242520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x000072fce12969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x000072fce1242476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x000072fce12287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x00000000008074fd llvm::json::operator==(llvm::json::Value const&, llvm::json::Value const&) (.cold) JSON.cpp:0:0
 #7 0x00000000053bec18 (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x53bec18)
 #8 0x00000000052bb868 (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x52bb868)
 #9 0x000000000093768e llvm::detail::PassModel<llvm::Module, llvm::VerifierPass, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x93768e)
#10 0x000000000527a030 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x527a030)
#11 0x0000000000941b4a llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::ArrayRef<std::function<void (llvm::PassBuilder&)>>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x941b4a)
#12 0x000000000093522c optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x93522c)
#13 0x000072fce1229d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#14 0x000072fce1229e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#15 0x000000000092cd35 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x92cd35)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```


Fix patch:
commit 605a9f590d91a42ae652c2ab13487b5ad57c58a5
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Fri Mar 14 13:40:15 2025 -0700

    [SLP]Check if user node is same as other node and check operand order
    
    Need to check if the user node is same as other node and check operand
    order to prevent a compiler crash when trying to find matching gather
    node with user nodes, having the same last instruction.
    
    Fixes #131195

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 9c3992b4a713..708dda9bd7f8 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -14081,6 +14081,17 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
     }
     return true;
   };
+  auto CheckParentNodes = [&](const TreeEntry *User1, const TreeEntry *User2,
+                              unsigned EdgeIdx) {
+    const TreeEntry *Ptr1 = User1;
+    while (Ptr1) {
+      unsigned Idx = Ptr1->UserTreeIndex.EdgeIdx;
+      Ptr1 = Ptr1->UserTreeIndex.UserTE;
+      if (Ptr1 == User2)
+        return Idx < EdgeIdx;
+    }
+    return false;
+  };
   for (Value *V : VL) {
     if (isConstant(V) || !VisitedValue.insert(V).second)
       continue;
@@ -14121,6 +14132,9 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
             (TEUseEI.UserTE->Idx < UseEI.UserTE->Idx ||
              HasGatherUser(TEUseEI.UserTE)))
           continue;
+        // If the user node is the operand of the other user node - skip.
+        if (CheckParentNodes(TEUseEI.UserTE, UseEI.UserTE, UseEI.EdgeIdx))
+          continue;
       }
 
       // Check if the user node of the TE comes after user node of TEPtr,


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/X86/user-node-with-same-last-instr.ll
commands: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -slp-threshold=-99999 < %s
tests: test_name: <module>
test_body: 
define void @wombat(i32 %arg) {
;
bb:
  br label %bb1

bb1:
  br i1 false, label %bb2, label %bb5

bb2:
  %phi = phi i32 [ %or, %bb4 ], [ 0, %bb1 ]
  %phi3 = phi i32 [ %sub, %bb4 ], [ 0, %bb1 ]
  %or = or i32 %phi, 1
  %and = and i32 0, %phi
  %sub = sub i32 %phi3, %arg
  br label %bb4

bb4:
  br i1 false, label %bb2, label %bb5

bb5:
  %phi6 = phi i32 [ 0, %bb1 ], [ %and, %bb4 ]
  %phi7 = phi i32 [ 0, %bb1 ], [ %sub, %bb4 ]
  ret void
}