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 using -passes=slp-vectorizer -slp-threshold=-99999:

[reduced-stripped.ll.zip](https://github.com/user-attachments/files/20462672/reduced-stripped.ll.zip)

Reproducer: https://godbolt.org/z/sf4Kvsqxa

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 0x00000000055ff378 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x55ff378)
 #1 0x00000000055fcd04 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #2 0x00007a8d0c442520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x00007a8d0c4969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x00007a8d0c442476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x00007a8d0c4287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x0000000000810401 llvm::json::operator==(llvm::json::Value const&, llvm::json::Value const&) (.cold) JSON.cpp:0:0
 #7 0x000000000553a631 (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x553a631)
 #8 0x0000000005435df8 (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5435df8)
 #9 0x000000000094557e 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+0x94557e)
#10 0x00000000053f3af0 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x53f3af0)
#11 0x000000000094f9ca 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+0x94f9ca)
#12 0x000000000094319c optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x94319c)
#13 0x00007a8d0c429d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#14 0x00007a8d0c429e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#15 0x000000000093add5 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x93add5)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```



Fix patch:
commit cb648ba97003bc0aa94e86f8e89ea6e3e3d09a11
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Thu May 29 08:49:31 2025 -0700

    [SLP]Check if the user node has instructions, used only outside
    
    Gather nodes with parents, which scalar instructions are used only
    outside, are generated before the whole tree vectorization. Need to
    teach isGatherShuffledSingleRegisterEntry to check that such nodes are
    emitted first and they cannot depend on other nodes, which are emitted
    later.
    
    Fixes #141628

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 831703b375d9..3e7f4cb56c0b 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -15317,6 +15317,20 @@ BoUpSLP::isGatherShuffledSingleRegisterEntry(
           UserPHI ? UserPHI->getIncomingBlock(UseEI.EdgeIdx)->getTerminator()
                   : &getLastInstructionInBundle(UseEI.UserTE);
       if (TEInsertPt == InsertPt) {
+        // Check nodes, which might be emitted first.
+        if (TEUseEI.UserTE->State == TreeEntry::Vectorize &&
+            (TEUseEI.UserTE->getOpcode() != Instruction::PHI ||
+             TEUseEI.UserTE->isAltShuffle()) &&
+            all_of(TEUseEI.UserTE->Scalars,
+                   [](Value *V) { return isUsedOutsideBlock(V); })) {
+          if (UseEI.UserTE->State != TreeEntry::Vectorize ||
+              (UseEI.UserTE->getOpcode() == Instruction::PHI &&
+               !UseEI.UserTE->isAltShuffle()) ||
+              any_of(UseEI.UserTE->Scalars,
+                     [](Value *V) { return !isUsedOutsideBlock(V); }))
+            continue;
+        }
+
         // If the schedulable insertion point is used in multiple entries - just
         // exit, no known ordering at this point, available only after real
         // scheduling.


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/X86/many-uses-parent-node.ll
commands: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -slp-threshold=-99999 < %s
tests: test_name: <module>
test_body: 
define i32 @test(ptr addrspace(1) %arg) {
;
bb:
  br label %bb1

bb1:                                              ; preds = %bb
  %getelementptr = getelementptr i8, ptr addrspace(1) %arg, i64 20
  %getelementptr2 = getelementptr i8, ptr addrspace(1) %arg, i64 21
  %getelementptr3 = getelementptr i8, ptr addrspace(1) %arg, i64 22
  br i1 false, label %bb73, label %bb150
bb4:                                              ; No predecessors!
  br i1 false, label %bb68, label %bb70
bb5:                                              ; No predecessors!
  br i1 false, label %bb64, label %bb66
bb6:                                              ; No predecessors!
  br i1 false, label %bb60, label %bb62
bb7:                                              ; No predecessors!
  br i1 false, label %bb8, label %bb58
bb8:                                              ; preds = %bb7
  br i1 false, label %bb54, label %bb56
bb9:                                              ; No predecessors!
  br i1 false, label %bb50, label %bb52
bb10:                                             ; No predecessors!
  br i1 false, label %bb46, label %bb48
bb11:                                             ; No predecessors!
  br i1 false, label %bb42, label %bb44
bb12:                                             ; No predecessors!
  br i1 false, label %bb38, label %bb40
bb13:                                             ; No predecessors!
  br i1 false, label %bb36, label %bb122
bb14:                                             ; No predecessors!
  br i1 false, label %bb32, label %bb34
bb15:                                             ; No predecessors!
  br i1 false, label %bb28, label %bb30
bb16:                                             ; No predecessors!
  br i1 false, label %bb17, label %bb26
bb17:                                             ; preds = %bb16
  br i1 false, label %bb22, label %bb24
bb18:                                             ; No predecessors!
  br i1 false, label %bb19, label %bb20
bb19:                                             ; preds = %bb18
  %load = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb20:                                             ; preds = %bb18
  %load21 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb22:                                             ; preds = %bb17
  %load23 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb24:                                             ; preds = %bb17
  %load25 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb26:                                             ; preds = %bb16
  %load27 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb28:                                             ; preds = %bb15
  %load29 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb30:                                             ; preds = %bb15
  %load31 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb32:                                             ; preds = %bb14
  %load33 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb34:                                             ; preds = %bb14
  %load35 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb36:                                             ; preds = %bb13
  %load37 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb38:                                             ; preds = %bb12
  %load39 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb40:                                             ; preds = %bb12
  %load41 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb42:                                             ; preds = %bb11
  %load43 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb44:                                             ; preds = %bb11
  %load45 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb46:                                             ; preds = %bb10
  %load47 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb48:                                             ; preds = %bb10
  %load49 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb50:                                             ; preds = %bb9
  %load51 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb52:                                             ; preds = %bb9
  %load53 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb54:                                             ; preds = %bb8
  %load55 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb56:                                             ; preds = %bb8
  %load57 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb58:                                             ; preds = %bb7
  %load59 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb60:                                             ; preds = %bb6
  %load61 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb62:                                             ; preds = %bb6
  %load63 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb64:                                             ; preds = %bb5
  %load65 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb66:                                             ; preds = %bb5
  %load67 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb68:                                             ; preds = %bb4
  %load69 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb70:                                             ; preds = %bb4
  %load71 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb72:                                             ; No predecessors!
  br i1 false, label %bb142, label %bb79
bb73:                                             ; preds = %bb1
  br i1 false, label %bb146, label %bb74
bb74:                                             ; preds = %bb73
  br i1 false, label %bb75, label %bb76
bb75:                                             ; preds = %bb74
  br label %bb150
bb76:                                             ; preds = %bb74
  br i1 false, label %bb153, label %bb77
bb77:                                             ; preds = %bb76
  %load78 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb79:                                             ; preds = %bb72
  br i1 false, label %bb146, label %bb81
bb80:                                             ; No predecessors!
  br label %bb150
bb81:                                             ; preds = %bb79
  %load82 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb83:                                             ; No predecessors!
  br label %bb138
bb84:                                             ; No predecessors!
  br i1 false, label %bb142, label %bb85
bb85:                                             ; preds = %bb84
  br i1 false, label %bb146, label %bb86
bb86:                                             ; preds = %bb85
  %load87 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb88:                                             ; No predecessors!
  br label %bb134
bb89:                                             ; No predecessors!
  br i1 false, label %bb138, label %bb90
bb90:                                             ; preds = %bb89
  br i1 false, label %bb142, label %bb91
bb91:                                             ; preds = %bb90
  %load92 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb93:                                             ; No predecessors!
  br label %bb130
bb94:                                             ; No predecessors!
  br i1 false, label %bb134, label %bb95
bb95:                                             ; preds = %bb94
  br i1 false, label %bb138, label %bb96
bb96:                                             ; preds = %bb95
  %load97 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb98:                                             ; No predecessors!
  br label %bb126
bb99:                                             ; No predecessors!
  br i1 false, label %bb130, label %bb100
bb100:                                            ; preds = %bb99
  br i1 false, label %bb134, label %bb101
bb101:                                            ; preds = %bb100
  %load102 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb103:                                            ; No predecessors!
  br label %bb124
bb104:                                            ; No predecessors!
  br i1 false, label %bb126, label %bb105
bb105:                                            ; preds = %bb104
  br i1 false, label %bb130, label %bb106
bb106:                                            ; preds = %bb105
  %load107 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb108:                                            ; No predecessors!
  br label %bb124
bb109:                                            ; No predecessors!
  br i1 false, label %bb126, label %bb110
bb110:                                            ; preds = %bb109
  %load111 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb112:                                            ; No predecessors!
  %load113 = load i8, ptr addrspace(1) %getelementptr3, align 1
  br label %bb124
bb114:                                            ; No predecessors!
  %load115 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb116:                                            ; No predecessors!
  %load117 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb118:                                            ; No predecessors!
  %load119 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb120:                                            ; No predecessors!
  %load121 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0
bb122:                                            ; preds = %bb13
  %load123 = load i8, ptr addrspace(1) %getelementptr3, align 1
  ret i32 0

bb124:                                            ; preds = %bb112, %bb108, %bb103
  %phi = phi ptr addrspace(1) [ null, %bb112 ], [ %getelementptr3, %bb108 ], [ null, %bb103 ]
  %phi125 = phi ptr addrspace(1) [ null, %bb112 ], [ null, %bb108 ], [ %getelementptr3, %bb103 ]
  br label %bb126

bb126:                                            ; preds = %bb124, %bb109, %bb104, %bb98
  %phi127 = phi ptr addrspace(1) [ null, %bb124 ], [ null, %bb98 ], [ null, %bb104 ], [ %getelementptr3, %bb109 ]
  %phi128 = phi ptr addrspace(1) [ null, %bb124 ], [ null, %bb98 ], [ %getelementptr3, %bb104 ], [ null, %bb109 ]
  %phi129 = phi ptr addrspace(1) [ null, %bb124 ], [ %getelementptr3, %bb98 ], [ null, %bb104 ], [ null, %bb109 ]
  br label %bb130

bb130:                                            ; preds = %bb126, %bb105, %bb99, %bb93
  %phi131 = phi ptr addrspace(1) [ null, %bb126 ], [ null, %bb93 ], [ null, %bb99 ], [ %getelementptr3, %bb105 ]
  %phi132 = phi ptr addrspace(1) [ null, %bb126 ], [ null, %bb93 ], [ %getelementptr3, %bb99 ], [ null, %bb105 ]
  %phi133 = phi ptr addrspace(1) [ null, %bb126 ], [ %getelementptr3, %bb93 ], [ null, %bb99 ], [ null, %bb105 ]
  br label %bb134

bb134:                                            ; preds = %bb130, %bb100, %bb94, %bb88
  %phi135 = phi ptr addrspace(1) [ null, %bb130 ], [ null, %bb88 ], [ null, %bb94 ], [ %getelementptr3, %bb100 ]
  %phi136 = phi ptr addrspace(1) [ null, %bb130 ], [ null, %bb88 ], [ %getelementptr3, %bb94 ], [ null, %bb100 ]
  %phi137 = phi ptr addrspace(1) [ null, %bb130 ], [ %getelementptr3, %bb88 ], [ null, %bb94 ], [ null, %bb100 ]
  br label %bb138

bb138:                                            ; preds = %bb134, %bb95, %bb89, %bb83
  %phi139 = phi ptr addrspace(1) [ null, %bb134 ], [ null, %bb83 ], [ null, %bb89 ], [ %getelementptr3, %bb95 ]
  %phi140 = phi ptr addrspace(1) [ null, %bb134 ], [ null, %bb83 ], [ %getelementptr3, %bb89 ], [ null, %bb95 ]
  %phi141 = phi ptr addrspace(1) [ null, %bb134 ], [ %getelementptr3, %bb83 ], [ null, %bb89 ], [ null, %bb95 ]
  br label %bb142

bb142:                                            ; preds = %bb138, %bb90, %bb84, %bb72
  %phi143 = phi ptr addrspace(1) [ null, %bb138 ], [ null, %bb72 ], [ null, %bb84 ], [ %getelementptr3, %bb90 ]
  %phi144 = phi ptr addrspace(1) [ null, %bb138 ], [ null, %bb72 ], [ %getelementptr3, %bb84 ], [ null, %bb90 ]
  %phi145 = phi ptr addrspace(1) [ null, %bb138 ], [ %getelementptr3, %bb72 ], [ null, %bb84 ], [ null, %bb90 ]
  br label %bb146

bb146:                                            ; preds = %bb142, %bb85, %bb79, %bb73
  %phi147 = phi ptr addrspace(1) [ null, %bb142 ], [ null, %bb73 ], [ null, %bb79 ], [ %getelementptr3, %bb85 ]
  %phi148 = phi ptr addrspace(1) [ null, %bb142 ], [ null, %bb73 ], [ %getelementptr3, %bb79 ], [ null, %bb85 ]
  %phi149 = phi ptr addrspace(1) [ null, %bb142 ], [ %getelementptr3, %bb73 ], [ null, %bb79 ], [ null, %bb85 ]
  br label %bb150

bb150:                                            ; preds = %bb146, %bb80, %bb75, %bb1
  %phi151 = phi ptr addrspace(1) [ %getelementptr2, %bb75 ], [ %getelementptr3, %bb80 ], [ null, %bb146 ], [ %getelementptr, %bb1 ]
  %phi152 = phi ptr addrspace(1) [ %getelementptr3, %bb75 ], [ null, %bb80 ], [ null, %bb146 ], [ %getelementptr2, %bb1 ]
  br label %bb153

bb153:                                            ; preds = %bb150, %bb76
  %phi154 = phi ptr addrspace(1) [ null, %bb150 ], [ %getelementptr3, %bb76 ]
  ret i32 0
}