Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: getSameOpcode
Issue title: SLPVectorizer (hasOperandBundles() && "Don't call otherwise!") assertion trigger with verified module
Labels: llvm:SLPVectorizer
crash
Reported by: gbaraldi

SLPVectorize asserts while optimizing the following module
```llvm-ir
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-ni:10:11:12:13"
target triple = "arm64-apple-darwin23.5.0"

define swiftcc void @julia_multiparameter_a_res_17823() {
top:
  %0 = call double @llvm.maximum.f64(double 0.000000e+00, double 0.000000e+00) [ "jl_roots"(ptr null) ]
  %1 = fadd double %0, 0.000000e+00
  %2 = fmul double 0.000000e+00, %1
  %3 = fmul double %2, 0.000000e+00
  %4 = select i1 false, double 0.000000e+00, double %3
  %5 = call double @llvm.maximum.f64(double 0.000000e+00, double 0.000000e+00)
  %6 = fadd double %5, 0.000000e+00
  %7 = fmul double 0.000000e+00, %6
  %8 = fmul double %7, 0.000000e+00
  %9 = select i1 false, double 0.000000e+00, double %8
  %10 = fmul double %9, 0.000000e+00
  %11 = fadd double 0.000000e+00, %10
  %12 = getelementptr { double, [1 x [2 x double]] }, ptr null, i64 0, i32 1
  store double %11, ptr %12, align 8
  %13 = fmul double %4, 0.000000e+00
  %14 = fadd double %13, 0.000000e+00
  store double %14, ptr null, align 8
  ret void
}

; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
declare double @llvm.maximum.f64(double, double) #0

; uselistorder directives
uselistorder ptr @llvm.maximum.f64, { 1, 0 }

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
```

This also seems to trigger on godbolt on whatever version of trunk they have there
https://godbolt.org/z/favErWG5K


stacktrace:
>  #0 0x0000000004e258c8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4e258c8)
 #1 0x0000000004e2301c SignalHandler(int) Signals.cpp:0:0
 #2 0x00007c7148042520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x00007c71480969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x00007c7148042476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x00007c71480287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x00007c714802871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #7 0x00007c7148039e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
 #8 0x0000000003ee5e8f (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3ee5e8f)
 #9 0x0000000003f5e546 getSameOpcode(llvm::ArrayRef<llvm::Value*>, llvm::TargetLibraryInfo const&, unsigned int) (.constprop.1) SLPVectorizer.cpp:0:0
#10 0x0000000003f67928 llvm::slpvectorizer::BoUpSLP::LookAheadHeuristics::getShallowScore(llvm::Value*, llvm::Value*, llvm::Instruction*, llvm::Instruction*, llvm::ArrayRef<llvm::Value*>) const (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f67928)
#11 0x0000000003f67de0 llvm::slpvectorizer::BoUpSLP::LookAheadHeuristics::getScoreAtLevelRec(llvm::Value*, llvm::Value*, llvm::Instruction*, llvm::Instruction*, int, llvm::ArrayRef<llvm::Value*>) const (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f67de0)
#12 0x0000000003f6aaf5 llvm::slpvectorizer::BoUpSLP::VLOperands::getBestOperand(unsigned int, int, int, llvm::ArrayRef<llvm::slpvectorizer::BoUpSLP::VLOperands::ReorderingMode>, llvm::ArrayRef<llvm::Value*>) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f6aaf5)
#13 0x0000000003f6bfcb llvm::slpvectorizer::BoUpSLP::VLOperands::reorder() (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f6bfcb)
#14 0x0000000003f6c4f6 llvm::slpvectorizer::BoUpSLP::reorderInputsAccordingToOpcode(llvm::ArrayRef<llvm::Value*>, llvm::SmallVectorImpl<llvm::Value*>&, llvm::SmallVectorImpl<llvm::Value*>&, llvm::slpvectorizer::BoUpSLP const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f6c4f6)
#15 0x0000000003f702f4 llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>, unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f702f4)
#16 0x0000000003f70392 llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>, unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f70392)
#17 0x0000000003f70362 llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>, unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f70362)
#18 0x0000000003f7022b llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>, unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f7022b)
#19 0x0000000003f70362 llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>, unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f70362)
#20 0x0000000003f70362 llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>, unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f70362)
#21 0x0000000003f6fe47 llvm::slpvectorizer::BoUpSLP::buildTree_rec(llvm::ArrayRef<llvm::Value*>, unsigned int, llvm::slpvectorizer::BoUpSLP::EdgeInfo const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f6fe47)
#22 0x0000000003f71b59 llvm::slpvectorizer::BoUpSLP::buildTree(llvm::ArrayRef<llvm::Value*>) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f71b59)
#23 0x0000000003f94622 llvm::SLPVectorizerPass::vectorizeStoreChain(llvm::ArrayRef<llvm::Value*>, llvm::slpvectorizer::BoUpSLP&, unsigned int, unsigned int, unsigned int&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f94622)
#24 0x0000000003f95fb0 llvm::SLPVectorizerPass::vectorizeStores(llvm::ArrayRef<llvm::StoreInst*>, llvm::slpvectorizer::BoUpSLP&, llvm::DenseSet<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, llvm::DenseMapInfo<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, void>>&)::'lambda'(std::set<std::pair<unsigned int, int>, llvm::SLPVectorizerPass::vectorizeStores(llvm::ArrayRef<llvm::StoreInst*>, llvm::slpvectorizer::BoUpSLP&, llvm::DenseSet<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, llvm::DenseMapInfo<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, void>>&)::StoreDistCompare, std::allocator<std::pair<unsigned int, int>>> const&)::operator()(std::set<std::pair<unsigned int, int>, llvm::SLPVectorizerPass::vectorizeStores(llvm::ArrayRef<llvm::StoreInst*>, llvm::slpvectorizer::BoUpSLP&, llvm::DenseSet<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, llvm::DenseMapInfo<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, void>>&)::StoreDistCompare, std::allocator<std::pair<unsigned int, int>>> const&) const SLPVectorizer.cpp:0:0
#25 0x0000000003f97e88 llvm::SLPVectorizerPass::vectorizeStores(llvm::ArrayRef<llvm::StoreInst*>, llvm::slpvectorizer::BoUpSLP&, llvm::DenseSet<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, llvm::DenseMapInfo<std::tuple<llvm::Value*, llvm::Value*, llvm::Value*, llvm::Value*, unsigned int>, void>>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f97e88)
#26 0x0000000003f985b3 llvm::SLPVectorizerPass::vectorizeStoreChains(llvm::slpvectorizer::BoUpSLP&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f985b3)
#27 0x0000000003f9970f 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
#28 0x0000000003f9a163 llvm::SLPVectorizerPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x3f9a163)
#29 0x0000000002e1013e llvm::detail::PassModel<llvm::Function, llvm::SLPVectorizerPass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x2e1013e)
#30 0x0000000004c2e64c llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4c2e64c)
#31 0x0000000000db3bce llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xdb3bce)
#32 0x0000000004c2cf8e llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4c2cf8e)
#33 0x0000000000db563e llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xdb563e)
#34 0x0000000004c2ae9c llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4c2ae9c)
#35 0x00000000008d7b32 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+0x8d7b32)
#36 0x00000000008cacdc optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8cacdc)
#37 0x00007c7148029d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#38 0x00007c7148029e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#39 0x00000000008c212e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8c212e)


Fix patch:
commit 380beaec8633bad0148aec02f03a85d9a59b2a2d
Author: Gabriel Baraldi <baraldigabriel@gmail.com>
Date:   Tue Jul 2 09:15:51 2024 -0300

    Fix potential crash in SLPVectorizer caused by missing check (#95937)
    
    I'm not super familiar with this code, but it seems that we were just
    missing a check.
    
    The original code that triggered this did not have uselistorders but
    llvm-reduce created them and it reproduces the same issue in a way more
    compact way.
    
    Fixes https://github.com/llvm/llvm-project/issues/95016

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index c4876bb92a1c..868e9e2687f5 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -835,11 +835,11 @@ static InstructionsState getSameOpcode(ArrayRef<Value *> VL,
         auto *CallBase = cast<CallInst>(IBase);
         if (Call->getCalledFunction() != CallBase->getCalledFunction())
           return InstructionsState(VL[BaseIndex], nullptr, nullptr);
-        if (Call->hasOperandBundles() &&
+        if (Call->hasOperandBundles() && (!CallBase->hasOperandBundles() ||
             !std::equal(Call->op_begin() + Call->getBundleOperandsStartIndex(),
                         Call->op_begin() + Call->getBundleOperandsEndIndex(),
                         CallBase->op_begin() +
-                            CallBase->getBundleOperandsStartIndex()))
+                            CallBase->getBundleOperandsStartIndex())))
           return InstructionsState(VL[BaseIndex], nullptr, nullptr);
         Intrinsic::ID ID = getVectorIntrinsicIDForCall(Call, &TLI);
         if (ID != BaseID)


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/AArch64/uselistorder.ll
commands: opt < %s -passes=slp-vectorizer -S -pass-remarks-missed=slp-vectorizer 2>&1
tests: test_name: <module>
test_body: 
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-gnu"

; This test has UB but the crash in #95016 only happens with it
define void @uselistorder_test() {
;
  %max1 = call double @llvm.maximum.f64(double 0.000000e+00, double 0.000000e+00) [ "a_list"(ptr null) ]
  %add1 = fadd double %max1, 0.000000e+00
  %mul1 = fmul double 0.000000e+00, %add1
  %mul2 = fmul double %mul1, 0.000000e+00
  %sel1 = select i1 false, double 0.000000e+00, double %mul2
  %max2 = call double @llvm.maximum.f64(double 0.000000e+00, double 0.000000e+00)
  %add2 = fadd double %max2, 0.000000e+00
  %mul3 = fmul double 0.000000e+00, %add2
  %mul4 = fmul double %mul3, 0.000000e+00
  %sel2 = select i1 false, double 0.000000e+00, double %mul4
  %mul5 = fmul double %sel2, 0.000000e+00
  %add3 = fadd double 0.000000e+00, %mul5
  %gep1 = getelementptr { double, [1 x [2 x double]] }, ptr null, i64 0, i32 1
  store double %add3, ptr %gep1, align 8
  %mul6 = fmul double %sel1, 0.000000e+00
  %add4 = fadd double %mul6, 0.000000e+00
  store double %add4, ptr null, align 8
  ret void
}

declare double @llvm.maximum.f64(double, double) #0

attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }