Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: BoUpSLP::reorderBottomToTop
Issue title: clang crashes at -O{s,2,3} on x86_64-linux-gnu: Assertion `idx < size()' failed
Labels: llvm:SLPVectorizer
crash
Reported by: zhendongsu

It appears to be a recent regression as it doesn't reproduce with 20.1.0. 

Compiler Explorer: https://godbolt.org/z/31z58Pqnf

```
[507] % clangtk -v
clang version 21.0.0git (https://github.com/llvm/llvm-project.git da3ee9763266f9adedaac1b1b3162d14f951fc55)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /local/suz-local/software/local/clang-trunk/bin
Build config: +assertions
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/11
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/11
Candidate multilib: .;@m64
Selected multilib: .;@m64
[508] % 
[508] % clangtk -Os small.c
clang-21: /local/suz-local/software/clangbuild/llvm-project/llvm/include/llvm/ADT/SmallVector.h:291: T& llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::operator[](llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::size_type) [with T = llvm::Value*; <template-parameter-1-2> = void; llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::reference = llvm::Value*&; llvm::SmallVectorTemplateCommon<T, <template-parameter-1-2> >::size_type = long unsigned int]: Assertion `idx < size()' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.	Program arguments: /local/suz-local/software/local/clang-trunk/bin/clang-21 -cc1 -triple x86_64-unknown-linux-gnu -emit-obj -dumpdir a- -disable-free -clear-ast-before-backend -main-file-name small.c -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/local/suz-local/software/emitesting/bugs/20250314-clangtk-m64-O3-build-143933/delta -fcoverage-compilation-dir=/local/suz-local/software/emitesting/bugs/20250314-clangtk-m64-O3-build-143933/delta -resource-dir /local/suz-local/software/local/clang-trunk/lib/clang/21 -I /usr/local/include -I /local/suz-local/software/local/include -internal-isystem /local/suz-local/software/local/clang-trunk/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Os -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcolor-diagnostics -vectorize-loops -vectorize-slp -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/small-fb79f4.o -x c small.c
1.	<eof> parser at end of file
2.	Optimizer
3.	Running pass "function<eager-inv>(float2int,lower-constant-intrinsics,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;no-hoist-loads-stores-with-cond-faulting;sink-common-insts;speculate-blocks;simplify-cond-branch;no-speculate-unpredictables>,slp-vectorizer,vector-combine,instcombine<max-iterations=1;no-verify-fixpoint>,loop-unroll<O2>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;hoist-loads-stores-with-cond-faulting;no-sink-common-insts;speculate-blocks;simplify-cond-branch;speculate-unpredictables>)" on module "small.c"
4.	Running pass "slp-vectorizer" on function "g"
 #0 0x0000559c00edefcf llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x4577fcf)
 #1 0x0000559c00edc7a4 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #2 0x00007f26a38b4420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #3 0x00007f26a32eb00b raise /build/glibc-LcI20x/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #4 0x00007f26a32ca859 abort /build/glibc-LcI20x/glibc-2.31/stdlib/abort.c:81:7
 #5 0x00007f26a32ca729 get_sysdep_segment_value /build/glibc-LcI20x/glibc-2.31/intl/loadmsgcat.c:509:8
 #6 0x00007f26a32ca729 _nl_load_domain /build/glibc-LcI20x/glibc-2.31/intl/loadmsgcat.c:970:34
 #7 0x00007f26a32dbfd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #8 0x0000559c0296f55e llvm::reorderScalars(llvm::SmallVectorImpl<llvm::Value*>&, llvm::ArrayRef<int>) SLPVectorizer.cpp:0:0
 #9 0x0000559c02a36719 llvm::slpvectorizer::BoUpSLP::reorderBottomToTop(bool) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x60cf719)
#10 0x0000559c02a41c60 llvm::SLPVectorizerPass::tryToVectorizeList(llvm::ArrayRef<llvm::Value*>, llvm::slpvectorizer::BoUpSLP&, bool) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x60dac60)
#11 0x0000559c02a4712d bool tryToVectorizeSequence<llvm::Value>(llvm::SmallVectorImpl<llvm::Value*>&, llvm::function_ref<bool (llvm::Value*, llvm::Value*)>, llvm::function_ref<bool (llvm::Value*, llvm::Value*)>, llvm::function_ref<bool (llvm::ArrayRef<llvm::Value*>, bool)>, bool, llvm::slpvectorizer::BoUpSLP&) (.constprop.0) SLPVectorizer.cpp:0:0
#12 0x0000559c02a48b21 llvm::SLPVectorizerPass::vectorizeChainsInBlock(llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x60e1b21)
#13 0x0000559c02a50b66 llvm::SLPVectorizerPass::runImpl(llvm::Function&, llvm::ScalarEvolution*, llvm::TargetTransformInfo*, llvm::TargetLibraryInfo*, llvm::AAResults*, llvm::LoopInfo*, llvm::DominatorTree*, llvm::AssumptionCache*, llvm::DemandedBits*, llvm::OptimizationRemarkEmitter*) (.part.0) SLPVectorizer.cpp:0:0
#14 0x0000559c02a51733 llvm::SLPVectorizerPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x60ea733)
#15 0x0000559c024c7cf6 llvm::detail::PassModel<llvm::Function, llvm::SLPVectorizerPass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x5b60cf6)
#16 0x0000559c0084f7c9 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x3ee87c9)
#17 0x0000559bfe1397a6 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x17d27a6)
#18 0x0000559c0084e032 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x3ee7032)
#19 0x0000559bfe1373b6 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x17d03b6)
#20 0x0000559c0084da51 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x3ee6a51)
#21 0x0000559c0119ce4a (anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>&, std::unique_ptr<llvm::ToolOutputFile, std::default_delete<llvm::ToolOutputFile>>&, clang::BackendConsumer*) BackendUtil.cpp:0:0
#22 0x0000559c011a08a1 clang::emitBackendOutput(clang::CompilerInstance&, clang::CodeGenOptions&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x48398a1)
#23 0x0000559c018e0d91 clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x4f79d91)
#24 0x0000559c0326e6dc clang::ParseAST(clang::Sema&, bool, bool) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x69076dc)
#25 0x0000559c018e11b8 clang::CodeGenAction::ExecuteAction() (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x4f7a1b8)
#26 0x0000559c01bb7bc9 clang::FrontendAction::Execute() (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x5250bc9)
#27 0x0000559c01b38ece clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x51d1ece)
#28 0x0000559c01cac996 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x5345996)
#29 0x0000559bfdccc9ed cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x13659ed)
#30 0x0000559bfdcc415a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#31 0x0000559bfdcc83c7 clang_main(int, char**, llvm::ToolContext const&) (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x13613c7)
#32 0x0000559bfdbad0db main (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x12460db)
#33 0x00007f26a32cc083 __libc_start_main /build/glibc-LcI20x/glibc-2.31/csu/../csu/libc-start.c:342:3
#34 0x0000559bfdcc3bee _start (/local/suz-local/software/local/clang-trunk/bin/clang-21+0x135cbee)
clangtk: error: unable to execute command: Aborted
clangtk: error: clang frontend command failed due to signal (use -v to see invocation)
clang version 21.0.0git (https://github.com/llvm/llvm-project.git da3ee9763266f9adedaac1b1b3162d14f951fc55)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /local/suz-local/software/local/clang-trunk/bin
Build config: +assertions
clangtk: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clangtk: note: diagnostic msg: /tmp/small-d812eb.c
clangtk: note: diagnostic msg: /tmp/small-d812eb.sh
clangtk: note: diagnostic msg: 

********************
[509] % 
[509] % cat small.c
int printf(const char *, ...);
int a, b, c, d, e, f;
void g() {
  int i = 1, j = 0, k = 0, m;
  char l = 1;
  if (d)
  n : {
    a = j;
    if (e >= l) {
      printf("%ld", (long) j);
      goto o;
    }
  p:
    if (m)
      j = 1;
    if (b)
      goto q;
    printf("%ld", (long) j);
  }
  o : ;
  int r = k, s = -f, t = -(s / i);
  if (c) {
    t = k;
    int u = a;
    char v = u;
  q:
    m = u % v;
    l = 0;
  }
  i = s;
  k = t;
  b = r;
  if (a)
    goto p;
  goto n;
}
```



Fix patch:
commit fbf0276b6a7a7a4508c373cf87fc349569652659
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Fri Mar 14 14:07:01 2025 -0700

    [SLP] Reorder reuses mask, if it is not empty, for subvector operands
    
    If the subvector operands has reuses mask, need to reorder the mask, not
    the scalars, to prevent compiler crash due to mask/scalars size
    mismatch.
    
    Fixes #131360

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 708dda9bd7f8..d450336cbc3c 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -6665,6 +6665,8 @@ void BoUpSLP::reorderBottomToTop(bool IgnoreReorder) {
           // Clear ordering of the operand.
           if (!OpTE.ReorderIndices.empty()) {
             OpTE.ReorderIndices.clear();
+          } else if (!OpTE.ReuseShuffleIndices.empty()) {
+            reorderReuses(OpTE.ReuseShuffleIndices, Mask);
           } else {
             assert(OpTE.isGather() && "Expected only gather/buildvector node.");
             reorderScalars(OpTE.Scalars, Mask);


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/X86/reorder-reused-subvector.ll
commands: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -slp-threshold=-100 < %s
tests: test_name: <module>
test_body: 
define void @test(i32 %j.6, i32 %m.4, i8 %v.5, ptr %a, i1 %tobool14.not) {
;
entry:
  br label %n

entry.o_crit_edge:
  br label %o

n:
  %i.0 = phi i32 [ 0, %entry ], [ 1, %if.end18 ]
  %j.0 = phi i32 [ 0, %entry ], [ %j.6, %if.end18 ]
  %m.0 = phi i32 [ 0, %entry ], [ %m.4, %if.end18 ]
  %l.0 = phi i8 [ 0, %entry ], [ %l.4, %if.end18 ]
  %u.0 = phi i32 [ 0, %entry ], [ %u.5, %if.end18 ]
  store i32 %j.0, ptr %a, align 4
  %cmp.not.not = icmp eq i8 %l.0, 0
  br i1 %cmp.not.not, label %o.sink.split, label %p

p:
  %0 = phi i32 [ %r.3, %if.end18 ], [ 0, %n ]
  %i.1 = phi i32 [ %s.3, %if.end18 ], [ 1, %n ]
  %j.1 = phi i32 [ %j.65, %if.end18 ], [ %j.0, %n ]
  %k.1 = phi i32 [ %t.3, %if.end18 ], [ %i.0, %n ]
  %m.1 = phi i32 [ %m.46, %if.end18 ], [ %m.0, %n ]
  %l.1 = phi i8 [ 1, %if.end18 ], [ 0, %n ]
  %s.1 = phi i32 [ %s.3, %if.end18 ], [ 0, %n ]
  %t.1 = phi i32 [ %t.3, %if.end18 ], [ 0, %n ]
  %u.12 = phi i32 [ %u.5, %if.end18 ], [ 0, %n ]
  %v.1 = phi i8 [ 0, %if.end18 ], [ %v.5, %n ]
  %tobool4.not = icmp eq i32 %m.1, 0
  %spec.select = select i1 %tobool4.not, i32 %j.1, i32 0
  %tobool7.not = icmp eq i32 %0, 0
  br i1 %tobool7.not, label %o.sink.split, label %q

o.sink.split:
  %spec.select.sink = phi i32 [ %j.0, %n ], [ %spec.select, %p ]
  %i.3.ph = phi i32 [ 0, %n ], [ %i.1, %p ]
  %k.3.ph = phi i32 [ %i.0, %n ], [ %k.1, %p ]
  %m.3.ph = phi i32 [ %m.0, %n ], [ 0, %p ]
  %l.3.ph = phi i8 [ 0, %n ], [ %l.1, %p ]
  %u.3.ph = phi i32 [ %u.0, %n ], [ 1, %p ]
  %conv10 = zext i32 %spec.select.sink to i64
  %call11 = tail call i32 (ptr, ...) @printf(ptr null, i64 %conv10)
  br label %o

o:
  %j.4 = phi i32 [ 0, %entry.o_crit_edge ], [ %spec.select.sink, %o.sink.split ]
  %k.3 = phi i32 [ 0, %entry.o_crit_edge ], [ %k.3.ph, %o.sink.split ]
  %m.3 = phi i32 [ 0, %entry.o_crit_edge ], [ %m.3.ph, %o.sink.split ]
  %u.3 = phi i32 [ 0, %entry.o_crit_edge ], [ %u.3.ph, %o.sink.split ]
  %sub = sub i32 0, %j.6
  %div = sdiv i32 %sub, %i.3.ph
  %sub13 = sub i32 0, %div
  br i1 %tobool14.not, label %if.end18, label %q

q:
  %s.2 = phi i32 [ %s.1, %p ], [ 0, %o ]
  %t.2 = phi i32 [ %t.1, %p ], [ %k.3, %o ]
  %u.4 = phi i32 [ %u.12, %p ], [ 0, %o ]
  %v.44 = phi i8 [ %v.1, %p ], [ 0, %o ]
  %conv17 = sext i8 %v.44 to i32
  %rem = mul i32 %u.4, %conv17
  br label %if.end18

if.end18:
  %j.65 = phi i32 [ 0, %q ], [ %j.4, %o ]
  %m.46 = phi i32 [ %rem, %q ], [ %m.3, %o ]
  %l.4 = phi i8 [ 0, %q ], [ %l.3.ph, %o ]
  %r.3 = phi i32 [ 0, %q ], [ %k.3, %o ]
  %s.3 = phi i32 [ %s.2, %q ], [ %sub, %o ]
  %t.3 = phi i32 [ %t.2, %q ], [ %sub13, %o ]
  %u.5 = phi i32 [ 0, %q ], [ %u.3, %o ]
  br i1 %tobool14.not, label %n, label %p

}
declare i32 @printf(ptr, ...)