Bug type: crash
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp: replaceExtractElements
Issue title: [InstCombine] opt triggered assertion "hasUseList()" at -O1/O2/O3
Labels: llvm:instcombine
crash-on-valid
Reported by: XChy

Reproducer: https://godbolt.org/z/K9TMMvP6d
Testcase:
```llvm
define i64 @func_1(ptr %g_322, i32 %0, i1 %tobool, i8 %BS_VAR_11.0, i64 %cond) {
entry:
  br label %BS_LABEL_1

BS_LABEL_1:                                       ; preds = %cond.end24, %if.then, %entry
  %BS_VAR_11.01 = phi i8 [ 0, %entry ], [ %vecext, %if.then ], [ 0, %cond.end24 ]
  br i1 %tobool, label %if.then, label %if.end

if.then:                                          ; preds = %BS_LABEL_1
  %vecinit = insertelement <6 x i8> zeroinitializer, i8 %BS_VAR_11.0, i32 0
  %vecinit2 = insertelement <6 x i8> %vecinit, i8 0, i32 0
  %vecext = extractelement <6 x i8> %vecinit2, i64 %cond
  br label %BS_LABEL_1

if.end:                                           ; preds = %BS_LABEL_1
  %vecinit10 = insertelement <2 x i8> zeroinitializer, i8 %BS_VAR_11.01, i32 0
  %conv12 = zext <2 x i8> %vecinit10 to <2 x i64>
  %shuffle = shufflevector <2 x i64> %conv12, <2 x i64> zeroinitializer, <32 x i32> <i32 1, i32 1, i32 1, i32 2, i32 0, i32 3, i32 0, i32 0, i32 3, i32 0, i32 2, i32 3, i32 1, i32 3, i32 1, i32 1, i32 0, i32 2, i32 1, i32 1, i32 0, i32 2, i32 2, i32 1, i32 2, i32 1, i32 3, i32 1, i32 1, i32 3, i32 2, i32 1>
  %tobool19 = icmp ne i64 0, 0
  br i1 %tobool19, label %cond.true20, label %cond.false22

cond.true20:                                      ; preds = %if.end
  %1 = load <2 x i64>, ptr null, align 16
  br label %cond.end24

cond.false22:                                     ; preds = %if.end
  %vecext23 = extractelement <32 x i64> %shuffle, i32 0
  br label %cond.end24

cond.end24:                                       ; preds = %cond.false22, %cond.true20
  %cond25 = phi i64 [ 0, %cond.true20 ], [ %vecext23, %cond.false22 ]
  %vecinit26 = insertelement <32 x i64> %shuffle, i64 %cond25, i32 0
  %vecext57 = extractelement <32 x i64> %vecinit26, i32 %0
  %vecins = insertelement <1 x i64> zeroinitializer, i64 %vecext57, i32 0
  store <1 x i64> %vecins, ptr %g_322, align 8
  br label %BS_LABEL_1
}
```
Output:
```
opt: /root/llvm-project/llvm/include/llvm/IR/Value.h:395: llvm::Value::user_iterator llvm::Value::materialized_user_begin(): Assertion `hasUseList()' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace and instructions to reproduce the bug.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/opt -o /app/output.s -S -O1 <source>
1.	Running pass "function<eager-inv>(mem2reg,instcombine<max-iterations=1;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;no-hoist-loads-stores-with-cond-faulting;no-sink-common-insts;speculate-blocks;simplify-cond-branch;no-speculate-unpredictables>)" on module "<source>"
2.	Running pass "instcombine<max-iterations=1;no-verify-fixpoint>" on function "func_1"
 #0 0x00000000058da2e8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x58da2e8)
 #1 0x00000000058d7194 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #2 0x00007f13dc842520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x00007f13dc8969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x00007f13dc842476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x00007f13dc8287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x00007f13dc82871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #7 0x00007f13dc839e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
 #8 0x00000000049567e8 collectShuffleElements(llvm::Value*, llvm::SmallVectorImpl<int>&, llvm::Value*, llvm::InstCombinerImpl&, bool&) (.constprop.0) InstCombineVectorOps.cpp:0:0
 #9 0x0000000004959e2f llvm::InstCombinerImpl::visitInsertElementInst(llvm::InsertElementInst&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4959e2f)
#10 0x000000000483798e llvm::InstCombinerImpl::run() (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x483798e)
#11 0x00000000048394a6 combineInstructionsOverFunction(llvm::Function&, llvm::InstructionWorklist&, llvm::AAResults*, llvm::AssumptionCache&, llvm::TargetLibraryInfo&, llvm::TargetTransformInfo&, llvm::DominatorTree&, llvm::OptimizationRemarkEmitter&, llvm::BlockFrequencyInfo*, llvm::BranchProbabilityInfo*, llvm::ProfileSummaryInfo*, llvm::InstCombineOptions const&) (.isra.0) InstructionCombining.cpp:0:0
#12 0x000000000483aa2d llvm::InstCombinePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x483aa2d)
#13 0x0000000002bebaee llvm::detail::PassModel<llvm::Function, llvm::InstCombinePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x2bebaee)
#14 0x00000000056c19c1 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x56c19c1)
#15 0x0000000000eeb97e 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+0xeeb97e)
#16 0x00000000056bff2a llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x56bff2a)
#17 0x000000000097295e 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+0x97295e)
#18 0x00000000056bf8e1 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x56bf8e1)
#19 0x000000000097cb18 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, bool) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x97cb18)
#20 0x0000000000970cb7 optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x970cb7)
#21 0x00007f13dc829d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#22 0x00007f13dc829e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#23 0x0000000000967dc5 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x967dc5)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```
cc @nikic @dtcxzyw 

Comments: author: nikic
body: InstCombine-only test case:
```llvm
define i64 @test(ptr %arg, i32 %arg1, i1 %arg2, i8 %arg3, i64 %arg4) {
bb:
  br label %bb5

bb5:                                              ; preds = %bb12, %bb6, %bb
  %phi = phi i8 [ 0, %bb ], [ %extractelement, %bb6 ], [ 0, %bb12 ]
  br i1 %arg2, label %bb6, label %bb8

bb6:                                              ; preds = %bb5
  %extractelement = extractelement <6 x i8> zeroinitializer, i64 %arg4
  br label %bb5

bb8:                                              ; preds = %bb5
  %insertelement9 = insertelement <2 x i8> <i8 poison, i8 0>, i8 %phi, i64 0
  %zext = zext nneg <2 x i8> %insertelement9 to <2 x i64>
  %shufflevector = shufflevector <2 x i64> %zext, <2 x i64> zeroinitializer, <32 x i32> <i32 poison, i32 1, i32 1, i32 2, i32 0, i32 3, i32 0, i32 0, i32 3, i32 0, i32 2, i32 3, i32 1, i32 3, i32 1, i32 1, i32 0, i32 2, i32 1, i32 1, i32 0, i32 2, i32 2, i32 1, i32 2, i32 1, i32 3, i32 1, i32 1, i32 3, i32 2, i32 1>
  br label %bb10

bb10:                                             ; preds = %bb8
  br label %bb12

bb12:                                             ; preds = %bb10
  %extractelement11 = extractelement <2 x i64> %zext, i64 1
  %insertelement13 = insertelement <32 x i64> %shufflevector, i64 %extractelement11, i64 0
  %extractelement14 = extractelement <32 x i64> %insertelement13, i32 %arg1
  %insertelement15 = insertelement <1 x i64> poison, i64 %extractelement14, i64 0
  store <1 x i64> %insertelement15, ptr %arg, align 8
  br label %bb5
}
```
author: dtcxzyw
body: https://github.com/llvm/llvm-project/blob/e3aa00e517e58583f96ca62e2c654d9ce6dec060/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp#L773-L785

Fix patch:
commit 6eff26094a2c277d9f324545b8b26a02213ed5de
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Fri Sep 26 00:53:24 2025 +0800

    [InstCombine] Skip replaceExtractElements for ConstantData (#160575)
    
    Closes https://github.com/llvm/llvm-project/issues/160507.
    
    Note: Replacing other users except for `ExtElt` is a bit strange to me.
    I tried to only replace `ExtElt` with a new extractelement, but it
    caused regressions on `widen_extract2/3`.

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index b17cf17db158..6ef30663bf3c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -723,6 +723,11 @@ static bool replaceExtractElements(InsertElementInst *InsElt,
       NumExtElts >= NumInsElts)
     return false;
 
+  Value *ExtVecOp = ExtElt->getVectorOperand();
+  // Bail out on constant vectors.
+  if (isa<ConstantData>(ExtVecOp))
+    return false;
+
   // Create a shuffle mask to widen the extended-from vector using poison
   // values. The mask selects all of the values of the original vector followed
   // by as many poison values as needed to create a vector of the same length
@@ -733,7 +738,6 @@ static bool replaceExtractElements(InsertElementInst *InsElt,
   for (unsigned i = NumExtElts; i < NumInsElts; ++i)
     ExtendMask.push_back(-1);
 
-  Value *ExtVecOp = ExtElt->getVectorOperand();
   auto *ExtVecOpInst = dyn_cast<Instruction>(ExtVecOp);
   BasicBlock *InsertionBlock = (ExtVecOpInst && !isa<PHINode>(ExtVecOpInst))
                                    ? ExtVecOpInst->getParent()


Regression tests:
file: llvm/test/Transforms/InstCombine/insert-extract-shuffle.ll
commands: opt -S -passes=instcombine %s
tests: test_name: pr160507
test_body: define i64 @pr160507(ptr %arg, i32 %arg1, i1 %arg2, i8 %arg3, i64 %arg4) {
bb:
  br label %bb5

bb5:                                              ; preds = %bb12, %bb6, %bb
  %phi = phi i8 [ 0, %bb ], [ %extractelement, %bb6 ], [ 0, %bb12 ]
  br i1 %arg2, label %bb6, label %bb8

bb6:                                              ; preds = %bb5
  %extractelement = extractelement <2 x i8> zeroinitializer, i64 %arg4
  br label %bb5

bb8:                                              ; preds = %bb5
  %insertelement9 = insertelement <2 x i8> <i8 poison, i8 0>, i8 %phi, i64 0
  %zext = zext <2 x i8> %insertelement9 to <2 x i64>
  %shufflevector = shufflevector <2 x i64> %zext, <2 x i64> poison, <4 x i32> <i32 poison, i32 1, i32 1, i32 1>
  br label %bb10

bb10:                                             ; preds = %bb8
  br label %bb12

bb12:                                             ; preds = %bb10
  %extractelement11 = extractelement <2 x i64> %zext, i64 1
  %insertelement13 = insertelement <4 x i64> %shufflevector, i64 %extractelement11, i64 0
  %extractelement14 = extractelement <4 x i64> %insertelement13, i32 %arg1
  store i64 %extractelement14, ptr %arg, align 8
  br label %bb5
}

test_name: infloop_D151807
test_body: define <4 x i32> @infloop_D151807(<4 x float> %arg) {
  %i = shufflevector <4 x float> %arg, <4 x float> poison, <2 x i32> <i32 2, i32 poison>
  %i1 = bitcast <2 x float> %i to <2 x i32>
  %i3 = extractelement <2 x i32> %i1, i64 0
  %i4 = insertelement <4 x i32> zeroinitializer, i32 %i3, i64 0
  ret <4 x i32> %i4
}