Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: tryToReduce
Issue title: Crash in getSameOpcode(llvm::ArrayRef<llvm::Value*>, llvm::TargetLibraryInfo const&, unsigned int)
Labels: llvm:SLPVectorizer
crash
Reported by: TatyanaDoubts

 To reproduce run 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() #0 gc "statepoint-example" {
bb:
  br label %bb1

bb1:                                              ; preds = %bb1, %bb
  %phi = phi i32 [ 0, %bb ], [ %mul9, %bb1 ]
  %phi2 = phi i32 [ 0, %bb ], [ 0, %bb1 ]
  %trunc = trunc i64 0 to i32
  %mul = mul i32 0, %trunc
  %mul3 = mul i32 %trunc, %phi
  %mul4 = mul i32 %mul3, %mul
  %mul5 = mul i32 %mul4, %mul
  %trunc6 = trunc i64 0 to i32
  %mul7 = mul i32 0, %trunc6
  %mul8 = mul i32 %mul5, %mul7
  %mul9 = mul i32 %mul8, %mul7
  br label %bb1
}

```
Reproducer: https://godbolt.org/z/sqEov8n9h

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 "function(slp-vectorizer)" on module "<source>"
2.	Running pass "slp-vectorizer" on function "wombat"
 #0 0x0000000004f2ff18 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4f2ff18)
 #1 0x0000000004f2d68c SignalHandler(int) Signals.cpp:0:0
 #2 0x00007a3cdfe42520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x000000000403fb8a getSameOpcode(llvm::ArrayRef<llvm::Value*>, llvm::TargetLibraryInfo const&, unsigned int) (.constprop.1) SLPVectorizer.cpp:0:0
 #4 0x000000000406b0a4 (anonymous namespace)::HorizontalReduction::tryToReduce(llvm::slpvectorizer::BoUpSLP&, llvm::DataLayout const&, llvm::TargetTransformInfo*, llvm::TargetLibraryInfo const&) SLPVectorizer.cpp:0:0
 #5 0x000000000406dab4 llvm::SLPVectorizerPass::vectorizeHorReduction(llvm::PHINode*, llvm::Instruction*, llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&, llvm::TargetTransformInfo*, llvm::SmallVectorImpl<llvm::WeakTrackingVH>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x406dab4)
 #6 0x00000000040720f8 llvm::SLPVectorizerPass::vectorizeRootInstruction(llvm::PHINode*, llvm::Instruction*, llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&, llvm::TargetTransformInfo*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x40720f8)
 #7 0x00000000040763be llvm::SLPVectorizerPass::vectorizeChainsInBlock(llvm::BasicBlock*, llvm::slpvectorizer::BoUpSLP&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x40763be)
 #8 0x000000000407c648 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
 #9 0x000000000407d11b llvm::SLPVectorizerPass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x407d11b)
#10 0x0000000002e7f61e 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+0x2e7f61e)
#11 0x0000000004d2d348 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4d2d348)
#12 0x0000000000de6cce 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+0xde6cce)
#13 0x0000000004d2bd3e llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4d2bd3e)
#14 0x0000000000de731e 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+0xde731e)
#15 0x0000000004d29ea0 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4d29ea0)
#16 0x00000000008e4312 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+0x8e4312)
#17 0x00000000008d723c optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8d723c)
#18 0x00007a3cdfe29d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#19 0x00007a3cdfe29e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#20 0x00000000008ce6ae _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x8ce6ae)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```

Comments: author: RKSimon
body: CC @alexey-bataev 

Fix patch:
commit 441f94f4bdf6e2b9747ec12194c595098d9c3a5b
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Wed Aug 7 04:09:55 2024 -0700

    [SLP]Fix PR102279: check the tracked values for extractelements, not the original values
    
    If the reduced value was replaced by the extractelement instruction
    during vectorization and we attempt to check if this is so, need to
    check the tracked value, not the original (deleted) instruction.
    Otherwise, the compiler may crash
    
    Fixes https://github.com/llvm/llvm-project/issues/102279

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index c9335b7a89e1..1fee06d145b9 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -17336,27 +17336,23 @@ public:
       // Try to handle shuffled extractelements.
       if (S.getOpcode() == Instruction::ExtractElement && !S.isAltShuffle() &&
           I + 1 < E) {
-        InstructionsState NextS = getSameOpcode(ReducedVals[I + 1], TLI);
-        if (NextS.getOpcode() == Instruction::ExtractElement &&
-            !NextS.isAltShuffle()) {
-          SmallVector<Value *> CommonCandidates(Candidates);
-          for (Value *RV : ReducedVals[I + 1]) {
-            Value *RdxVal = TrackedVals.find(RV)->second;
-            // Check if the reduction value was not overriden by the
-            // extractelement instruction because of the vectorization and
-            // exclude it, if it is not compatible with other values.
-            if (auto *Inst = dyn_cast<Instruction>(RdxVal))
-              if (!NextS.getOpcode() || !NextS.isOpcodeOrAlt(Inst))
-                continue;
-            CommonCandidates.push_back(RdxVal);
-            TrackedToOrig.try_emplace(RdxVal, RV);
-          }
-          SmallVector<int> Mask;
-          if (isFixedVectorShuffle(CommonCandidates, Mask)) {
-            ++I;
-            Candidates.swap(CommonCandidates);
-            ShuffledExtracts = true;
-          }
+        SmallVector<Value *> CommonCandidates(Candidates);
+        for (Value *RV : ReducedVals[I + 1]) {
+          Value *RdxVal = TrackedVals.find(RV)->second;
+          // Check if the reduction value was not overriden by the
+          // extractelement instruction because of the vectorization and
+          // exclude it, if it is not compatible with other values.
+          auto *Inst = dyn_cast<ExtractElementInst>(RdxVal);
+          if (!Inst)
+            continue;
+          CommonCandidates.push_back(RdxVal);
+          TrackedToOrig.try_emplace(RdxVal, RV);
+        }
+        SmallVector<int> Mask;
+        if (isFixedVectorShuffle(CommonCandidates, Mask)) {
+          ++I;
+          Candidates.swap(CommonCandidates);
+          ShuffledExtracts = true;
         }
       }
 


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/X86/reduced-value-replace-extractelement.ll
commands: opt -S --passes=slp-vectorizer -slp-threshold=-99999 < %s -mtriple=x86_64-unknown-linux-gnu
tests: test_name: test
test_body: define void @test() {
bb:
  br label %bb1

bb1:                                              ; preds = %bb1, %bb
  %phi = phi i32 [ 0, %bb ], [ %mul9, %bb1 ]
  %phi2 = phi i32 [ 0, %bb ], [ 0, %bb1 ]
  %trunc = trunc i64 0 to i32
  %mul = mul i32 0, %trunc
  %mul3 = mul i32 %trunc, %phi
  %mul4 = mul i32 %mul3, %mul
  %mul5 = mul i32 %mul4, %mul
  %trunc6 = trunc i64 0 to i32
  %mul7 = mul i32 0, %trunc6
  %mul8 = mul i32 %mul5, %mul7
  %mul9 = mul i32 %mul8, %mul7
  br label %bb1
}

file: llvm/test/Transforms/SLPVectorizer/X86/reduction-gather-non-scheduled-extracts.ll
commands: opt -S --passes=slp-vectorizer -mtriple=x86_64-sie-ps5 < %s
tests: test_name: tes
test_body: define void @tes() {
entry:
  %0 = extractelement <2 x i1> zeroinitializer, i64 0
  %1 = extractelement <2 x i1> zeroinitializer, i64 0
  %2 = fcmp ole <2 x double> zeroinitializer, zeroinitializer
  %3 = extractelement <2 x i1> %2, i64 0
  %4 = extractelement <2 x i1> zeroinitializer, i64 0
  br label %5

5:                                                ; preds = %entry
  %6 = select i1 false, i1 false, i1 false
  %7 = select i1 %6, i1 %0, i1 false
  %8 = select i1 %7, i1 %1, i1 false
  %9 = select i1 %8, i1 false, i1 false
  %10 = select i1 %9, i1 %3, i1 false
  %11 = select i1 %10, i1 %4, i1 false
  br i1 %11, label %12, label %13

12:                                               ; preds = %5
  ret void

13:                                               ; preds = %5
  ret void
}