Bug type: crash
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp: InstCombinerImpl::visitShuffleVectorInst
Issue title: [InstCombine] Assertion `!areInvalidOperands(C, S1, S2) && "Invalid operands for select"' failed.
Labels: llvm:instcombine
crash-on-valid
Reported by: dtcxzyw

Reproducer: 
```
; bin/opt -passes=instcombine reduced.ll -S
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"
target triple = "x86_64-pc-linux-gnu"

define <32 x float> @process(<8 x i1> %0) {
  %3 = select <8 x i1> %0, <8 x float> zeroinitializer, <8 x float> <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
  %4 = shufflevector <8 x float> %3, <8 x float> zeroinitializer, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
  %5 = shufflevector <16 x float> %4, <16 x float> zeroinitializer, <32 x i32> <i32 0, i32 8, i32 16, i32 24, i32 1, i32 9, i32 17, i32 25, i32 2, i32 10, i32 18, i32 26, i32 3, i32 11, i32 19, i32 27, i32 4, i32 12, i32 20, i32 28, i32 5, i32 13, i32 21, i32 29, i32 6, i32 14, i32 22, i32 30, i32 7, i32 15, i32 23, i32 31>
  ret <32 x float> %5
}
```
```
opt: /home/dtcxzyw/WorkSpace/Projects/compilers/llvm-project/llvm/include/llvm/IR/Instructions.h:1614: void llvm::SelectInst::init(llvm::Value*, llvm::Value*, llvm::Value*): Assertion `!areInvalidOperands(C, S1, S2) && "Invalid operands for select"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.      Program arguments: bin/opt -passes=instcombine reduced.ll
1.      Running pass "function(instcombine<max-iterations=1;verify-fixpoint>)" on module "reduced.ll"
2.      Running pass "instcombine<max-iterations=1;verify-fixpoint>" on function "process"
 #0 0x00007ffff7e15b02 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.20.0git+0x215b02)
 #1 0x00007ffff7e129af llvm::sys::RunSignalHandlers() (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMSupport.so.20.0git+0x2129af)
 #2 0x00007ffff7e12af5 SignalHandler(int) Signals.cpp:0:0
 #3 0x00007ffff7842520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #4 0x00007ffff78969fc __pthread_kill_implementation ./nptl/pthread_kill.c:44:76
 #5 0x00007ffff78969fc __pthread_kill_internal ./nptl/pthread_kill.c:78:10
 #6 0x00007ffff78969fc pthread_kill ./nptl/pthread_kill.c:89:10
 #7 0x00007ffff7842476 gsignal ./signal/../sysdeps/posix/raise.c:27:6
 #8 0x00007ffff78287f3 abort ./stdlib/abort.c:81:7
 #9 0x00007ffff782871b _nl_load_domain ./intl/loadmsgcat.c:1177:9
#10 0x00007ffff7839e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#11 0x00007ffff1272963 llvm::InstCombinerImpl::FoldOpIntoSelect(llvm::Instruction&, llvm::SelectInst*, bool) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.20.0git+0x60963)
#12 0x00007ffff13a09d1 llvm::InstCombinerImpl::visitShuffleVectorInst(llvm::ShuffleVectorInst&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.20.0git+0x18e9d1)
#13 0x00007ffff1275da8 llvm::InstCombinerImpl::run() (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.20.0git+0x63da8)
#14 0x00007ffff1276f09 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&) InstructionCombining.cpp:0:0
#15 0x00007ffff1277dfb llvm::InstCombinePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMInstCombine.so.20.0git+0x65dfb)
#16 0x00007ffff30d9955 llvm::detail::PassModel<llvm::Function, llvm::InstCombinePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMPasses.so.20.0git+0xd9955)
#17 0x00007ffff01678bd llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMCore.so.20.0git+0x3678bd)
#18 0x00007ffff68d9e65 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMX86CodeGen.so.20.0git+0xd9e65)
#19 0x00007ffff01659f6 llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMCore.so.20.0git+0x3659f6)
#20 0x00007ffff68da825 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMX86CodeGen.so.20.0git+0xda825)
#21 0x00007ffff016657a llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/../lib/libLLVMCore.so.20.0git+0x36657a)
#22 0x00007ffff7f95051 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) (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMOptDriver.so.20.0git+0x2d051)
#23 0x00007ffff7fa073f optMain (/home/dtcxzyw/WorkSpace/Projects/compilers/LLVM/llvm-build/bin/../lib/libLLVMOptDriver.so.20.0git+0x3873f)
#24 0x00007ffff7829d90 __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#25 0x00007ffff7829e40 call_init ./csu/../csu/libc-start.c:128:20
#26 0x00007ffff7829e40 __libc_start_main ./csu/../csu/libc-start.c:379:5
#27 0x0000555555555095 _start (bin/opt+0x1095)
Aborted (core dumped)
```

It is caused by https://github.com/llvm/llvm-project/pull/113746. We cannot do this fold if the output and input operands don't have the exact same type. It was reported by llvm-opt-benchmark pre-commit test https://github.com/dtcxzyw/llvm-opt-benchmark/pull/1543. I am sorry I didn't notice about this. Fortunately this issue was captured by a post-commit test https://github.com/dtcxzyw/llvm-opt-benchmark/issues/1560.

cc @MatzeB @RKSimon @goldsteinn 

I will post a fix later.





Fix patch:
commit 18311093abe6481388a0d963d58438d743b47569
Author: Yingwei Zheng <dtcxzyw2333@gmail.com>
Date:   Tue Oct 29 10:39:07 2024 +0800

    [InstCombine] Do not fold `shufflevector(select)` if the select condition is a vector (#113993)
    
    Since `shufflevector` is not element-wise, we cannot do fold it into
    select when the select condition is a vector.
    For shufflevector that doesn't change the length, it doesn't crash, but
    it is still a miscompilation: https://alive2.llvm.org/ce/z/s8saCx
    
    Fixes https://github.com/llvm/llvm-project/issues/113986.

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index 75e7c1c97018..454fe5a91d37 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -2902,8 +2902,12 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
 
   if (match(RHS, m_Constant())) {
     if (auto *SI = dyn_cast<SelectInst>(LHS)) {
-      if (Instruction *I = FoldOpIntoSelect(SVI, SI))
-        return I;
+      // We cannot do this fold for elementwise select since ShuffleVector is
+      // not elementwise.
+      if (SI->getCondition()->getType()->isIntegerTy()) {
+        if (Instruction *I = FoldOpIntoSelect(SVI, SI))
+          return I;
+      }
     }
     if (auto *PN = dyn_cast<PHINode>(LHS)) {
       if (Instruction *I = foldOpIntoPhi(SVI, PN))


Regression tests:
file: llvm/test/Transforms/InstCombine/vec_shuffle.ll
commands: opt < %s -passes=instcombine -S
tests: test_name: foldselect0
test_body: define <2 x i32> @foldselect0(i1 %c) {
  %sel = select i1 %c, <2 x i32> <i32 42, i32 7>, <2 x i32> <i32 0, i32 1>
  %shuf = shufflevector <2 x i32> %sel, <2 x i32> poison, <2 x i32> <i32 1, i32 0>
  ret <2 x i32> %shuf
}

test_name: shuf_larger_length_vec_select
test_body: define <4 x float> @shuf_larger_length_vec_select(<2 x i1> %cond) {
  %sel = select <2 x i1> %cond, <2 x float> zeroinitializer, <2 x float> splat (float 1.000000e+00)
  %shuf = shufflevector <2 x float> %sel, <2 x float> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
  ret <4 x float> %shuf
}

test_name: shuf_same_length_vec_select
test_body: define <4 x i32> @shuf_same_length_vec_select(<4 x i1> %cond) {
  %sel = select <4 x i1> %cond, <4 x i32> <i32 0, i32 1, i32 2, i32 3>, <4 x i32> <i32 4, i32 5, i32 6, i32 7>
  %shuf = shufflevector <4 x i32> %sel, <4 x i32> <i32 8, i32 9, i32 10, i32 11>, <4 x i32> <i32 2, i32 1, i32 3, i32 5>
  ret <4 x i32> %shuf
}