Bug type: crash
Component: InstCombine
Bug location: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp: InstCombinerImpl::foldICmpBinOpWithConstantViaTruthTable
Issue title: [InstCombine] Assertion `New->getType() == getType() && "replaceAllUses of value with new value of different type!"' failed.
Labels: llvm:instcombine
crash-on-valid
Reported by: XChy

Reproducer: https://godbolt.org/z/raT3GvvGv
Testcase:
```llvm
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-musl"

define <2 x i1> @func_1(i1 %tobool117.not, <2 x i1> %0) {
entry:
  %cond131 = select i1 %tobool117.not, <8 x i8> <i8 poison, i8 poison, i8 poison, i8 9, i8 9, i8 poison, i8 poison, i8 poison>, <8 x i8> zeroinitializer
  %1 = shufflevector <8 x i8> %cond131, <8 x i8> zeroinitializer, <2 x i32> <i32 3, i32 4>
  %2 = select <2 x i1> %0, <2 x i16> splat (i16 179), <2 x i16> splat (i16 1)
  %3 = zext <2 x i8> %1 to <2 x i16>
  %4 = lshr <2 x i16> splat (i16 255), %3
  %5 = and <2 x i16> %2, %4
  %6 = icmp eq <2 x i16> %5, zeroinitializer
  ret <2 x i1> %6
}
```

Dump:
```
opt: /root/llvm-project/llvm/lib/IR/Value.cpp:519: void llvm::Value::doRAUW(llvm::Value*, llvm::Value::ReplaceMetadataUses): Assertion `New->getType() == getType() && "replaceAllUses of value with new value of different type!"' 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 --passes=instcombine <source>
1.	Running pass "function(instcombine<max-iterations=1;verify-fixpoint>)" on module "<source>"
2.	Running pass "instcombine<max-iterations=1;verify-fixpoint>" on function "func_1"
 #0 0x00000000059be998 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x59be998)
 #1 0x00000000059bb844 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #2 0x0000729660842520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x00007296608969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x0000729660842476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x00007296608287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x000072966082871b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #7 0x0000729660839e96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
 #8 0x00000000057d3bb2 (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x57d3bb2)
 #9 0x0000000000cc0924 llvm::InstCombiner::replaceInstUsesWith(llvm::Instruction&, llvm::Value*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0xcc0924)
#10 0x0000000004993735 llvm::InstCombinerImpl::foldICmpBinOpWithConstantViaTruthTable(llvm::ICmpInst&, llvm::BinaryOperator*, llvm::APInt const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4993735)
#11 0x00000000049b706e llvm::InstCombinerImpl::foldICmpInstWithConstant(llvm::ICmpInst&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x49b706e)
#12 0x00000000049c548e llvm::InstCombinerImpl::visitICmpInst(llvm::ICmpInst&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x49c548e)
#13 0x000000000490e023 llvm::InstCombinerImpl::run() (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x490e023)
#14 0x000000000490ff06 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
#15 0x0000000004911474 llvm::InstCombinePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4911474)
#16 0x0000000002ca3d4e 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+0x2ca3d4e)
#17 0x000000000579be41 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x579be41)
#18 0x0000000000f0774e 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+0xf0774e)
#19 0x000000000579a50a llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x579a50a)
#20 0x0000000000973a7e 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+0x973a7e)
#21 0x0000000005799ec1 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x5799ec1)
#22 0x000000000097ddaa 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+0x97ddaa)
#23 0x0000000000971c28 optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x971c28)
#24 0x0000729660829d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#25 0x0000729660829e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#26 0x00000000009686c5 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x9686c5)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```


Fix patch:
commit 0952ccc712ffc97943fbd0fc3c38a53e7aa875ac
Author: Hongyu Chen <xxs_chy@outlook.com>
Date:   Sun Dec 21 16:40:38 2025 +0800

    [InstCombine] Bail out on type mismatch in foldICmpBinOpWithConstantViaTruthTable (#173179)
    
    Fixes https://github.com/llvm/llvm-project/issues/173177
    The previous implementation doesn't consider cases like `<2 x i1>
    icmp(binop(sel <2 x i1>, sel i1))`.

diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 616cb04be9db..7f1ced9505b9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -3093,7 +3093,7 @@ Instruction *InstCombinerImpl::foldICmpBinOpWithConstantViaTruthTable(
               m_Select(m_Value(A), m_Constant(C1), m_Constant(C2)))) ||
       !match(BO->getOperand(1),
              m_Select(m_Value(B), m_Constant(C3), m_Constant(C4))) ||
-      Cmp.getType() != A->getType())
+      Cmp.getType() != A->getType() || Cmp.getType() != B->getType())
     return nullptr;
 
   std::bitset<4> Table;


Regression tests:
file: llvm/test/Transforms/InstCombine/icmp-binop.ll
commands: opt < %s -passes=instcombine -S
tests: test_name: mul_unkV_oddC_eq
test_body: define i1 @mul_unkV_oddC_eq(i32 %v) {
  %mul = mul i32 %v, 3
  %cmp = icmp eq i32 %mul, 0
  ret i1 %cmp
}

test_name: icmp_eq_or_of_selects_with_constant_vectorized_nonsplat
test_body: define <2 x i1> @icmp_eq_or_of_selects_with_constant_vectorized_nonsplat(<2 x i1> %a, <2 x i1> %b) {
  %s1 = select <2 x i1> %a, <2 x i64> splat (i64 65536), <2 x i64> zeroinitializer
  %s2 = select <2 x i1> %b, <2 x i64> <i64 256, i64 128>, <2 x i64> zeroinitializer
  %or = or <2 x i64> %s1, %s2
  %cmp = icmp eq <2 x i64> %or, <i64 65792, i64 65664>
  ret <2 x i1> %cmp
}

test_name: pr173177
test_body: define <2 x i1> @pr173177(<2 x i1> %a, i1 %b) {
entry:
  %s1 = select <2 x i1> %a, <2 x i16> splat (i16 179), <2 x i16> splat (i16 1)
  %s2 = select i1 %b, <2 x i16> zeroinitializer, <2 x i16> splat (i16 255)
  %and = and <2 x i16> %s1, %s2
  %cmp = icmp eq <2 x i16> %and, zeroinitializer
  ret <2 x i1> %cmp
}