Bug type: crash
Component: IR
Bug location: llvm/lib/IR/Instructions.cpp: CastInst::isEliminableCastPair
Issue title: [GlobalOpt] Invalid Cast Combination UNREACHABLE executed at /root/llvm-project/llvm/lib/IR/Instructions.cpp:3033!
Labels: crash
llvm:ir
Reported by: k-arrows

Reproducer:
https://godbolt.org/z/Ge3Wo889v

Backtrace:
```console
Invalid Cast Combination
UNREACHABLE executed at /root/llvm-project/llvm/lib/IR/Instructions.cpp:3033!
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=globalopt <source>
1.	Running pass "globalopt" on module "<source>"
 #0 0x00000000057a24d8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x57a24d8)
 #1 0x000000000579f384 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
 #2 0x0000786f98642520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x0000786f986969fc pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x969fc)
 #4 0x0000786f98642476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #5 0x0000786f986287f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #6 0x00000000056d95ea (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x56d95ea)
 #7 0x00000000055013fb llvm::CastInst::isEliminableCastPair(llvm::Instruction::CastOps, llvm::Instruction::CastOps, llvm::Type*, llvm::Type*, llvm::Type*, llvm::Type*, llvm::Type*, llvm::Type*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x55013fb)
 #8 0x00000000053d084e llvm::ConstantFoldCastInstruction(unsigned int, llvm::Constant*, llvm::Type*) (.part.0) ConstantFold.cpp:0:0
 #9 0x0000000005405f77 getFoldedCast(llvm::Instruction::CastOps, llvm::Constant*, llvm::Type*, bool) Constants.cpp:0:0
#10 0x0000000004b90447 llvm::ConstantFoldCastOperand(unsigned int, llvm::Constant*, llvm::Type*, llvm::DataLayout const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4b90447)
#11 0x0000000004b9995e (anonymous namespace)::ConstantFoldInstOperandsImpl(llvm::Value const*, unsigned int, llvm::ArrayRef<llvm::Constant*>, llvm::DataLayout const&, llvm::TargetLibraryInfo const*, bool) ConstantFolding.cpp:0:0
#12 0x0000000004b9a368 (anonymous namespace)::ConstantFoldConstantImpl(llvm::Constant const*, llvm::DataLayout const&, llvm::TargetLibraryInfo const*, llvm::SmallDenseMap<llvm::Constant*, llvm::Constant*, 4u, llvm::DenseMapInfo<llvm::Constant*, void>, llvm::detail::DenseMapPair<llvm::Constant*, llvm::Constant*>>&) (.part.0) ConstantFolding.cpp:0:0
#13 0x0000000004b9a7c3 llvm::ConstantFoldConstant(llvm::Constant const*, llvm::DataLayout const&, llvm::TargetLibraryInfo const*) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x4b9a7c3)
#14 0x00000000030b3271 optimizeGlobalsInModule(llvm::Module&, llvm::DataLayout const&, llvm::function_ref<llvm::TargetLibraryInfo& (llvm::Function&)>, llvm::function_ref<llvm::TargetTransformInfo& (llvm::Function&)>, llvm::function_ref<llvm::BlockFrequencyInfo& (llvm::Function&)>, llvm::function_ref<llvm::DominatorTree& (llvm::Function&)>, llvm::function_ref<void (llvm::Function&)>, llvm::function_ref<void (llvm::Function&)>) (.constprop.0) GlobalOpt.cpp:0:0
#15 0x00000000030b480f llvm::GlobalOptPass::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x30b480f)
#16 0x0000000002e2aaee llvm::detail::PassModel<llvm::Module, llvm::GlobalOptPass, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x2e2aaee)
#17 0x000000000558c2f1 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x558c2f1)
#18 0x00000000009776b8 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+0x9776b8)
#19 0x000000000096b727 optMain (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x96b727)
#20 0x0000786f98629d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#21 0x0000786f98629e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#22 0x0000000000962845 _start (/opt/compiler-explorer/clang-assertions-trunk/bin/opt+0x962845)
Program terminated with signal: SIGSEGV
Compiler returned: 139
```

Comments: author: k-arrows
body: Reduced from the following:
https://github.com/llvm/llvm-project/blob/main/llvm/test/CodeGen/X86/ptrtoaddr.ll
author: k-arrows
body: This crash happens with opt(trunk) and opt(assertions trunk), and does not with opt 21.1.0
https://godbolt.org/z/839v3z4Mv


Fix patch:
commit f628a5467addf2f8a597141ab01f7e7453e6d9a7
Author: Hongyu Chen <xxs_chy@outlook.com>
Date:   Mon Sep 29 18:38:50 2025 +0800

    [ConstantFold] Fold inttoptr, ptrtoaddr to bitcast (#161087)
    
    Fixes #157334.

diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp
index daebf447a210..dd83168ab3c6 100644
--- a/llvm/lib/IR/Instructions.cpp
+++ b/llvm/lib/IR/Instructions.cpp
@@ -2847,6 +2847,7 @@ unsigned CastInst::isEliminableCastPair(
   // FPTRUNC       >       FloatPt      n/a        FloatPt      n/a
   // FPEXT         <       FloatPt      n/a        FloatPt      n/a
   // PTRTOINT     n/a      Pointer      n/a        Integral   Unsigned
+  // PTRTOADDR    n/a      Pointer      n/a        Integral   Unsigned
   // INTTOPTR     n/a      Integral   Unsigned     Pointer      n/a
   // BITCAST       =       FirstClass   n/a       FirstClass    n/a
   // ADDRSPCST    n/a      Pointer      n/a        Pointer      n/a
@@ -2878,7 +2879,7 @@ unsigned CastInst::isEliminableCastPair(
     { 99,99,99, 2, 2,99,99, 8, 2,99,99,99, 4, 0}, // FPExt          |
     {  1, 0, 0,99,99, 0, 0,99,99,99,99, 7, 3, 0}, // PtrToInt       |
     {  1, 0, 0,99,99, 0, 0,99,99,99,99, 0, 3, 0}, // PtrToAddr      |
-    { 99,99,99,99,99,99,99,99,99,11,99,99,15, 0}, // IntToPtr       |
+    { 99,99,99,99,99,99,99,99,99,11,11,99,15, 0}, // IntToPtr       |
     {  5, 5, 5, 0, 0, 5, 5, 0, 0,16,16, 5, 1,14}, // BitCast        |
     {  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,13,12}, // AddrSpaceCast -+
   };
@@ -2972,7 +2973,8 @@ unsigned CastInst::isEliminableCastPair(
       // zext, sext -> zext, because sext can't sign extend after zext
       return Instruction::ZExt;
     case 11: {
-      // inttoptr, ptrtoint -> bitcast if SrcSize<=PtrSize and SrcSize==DstSize
+      // inttoptr, ptrtoint/ptrtoaddr -> bitcast if SrcSize<=PtrSize and
+      // SrcSize==DstSize
       if (!MidIntPtrTy)
         return 0;
       unsigned PtrSize = MidIntPtrTy->getScalarSizeInBits();


Regression tests:
file: llvm/test/Transforms/InstCombine/ptrtoaddr.ll
commands: opt < %s -passes=instcombine -S
tests: test_name: <module>
test_body: target datalayout = "p1:64:64:64:32"

define i32 @ptrtoaddr_inttoptr_arg(i32 %a) {
;
  %toptr = inttoptr i32 %a to ptr addrspace(1)
  %toaddr = ptrtoaddr ptr addrspace(1) %toptr to i32
  ret i32 %toaddr
}

define i32 @ptrtoaddr_inttoptr() {
;
  ret i32 ptrtoaddr (ptr addrspace(1) inttoptr (i32 -1 to ptr addrspace(1)) to i32)
}

define i32 @ptrtoaddr_inttoptr_diff_size1() {
;
  ret i32 ptrtoaddr (ptr addrspace(1) inttoptr (i64 -1 to ptr addrspace(1)) to i32)
}

define i32 @ptrtoaddr_inttoptr_diff_size2() {
;
  ret i32 ptrtoaddr (ptr addrspace(1) inttoptr (i16 -1 to ptr addrspace(1)) to i32)
}

define i64 @ptrtoaddr_inttoptr_noas1() {
;
  ret i64 ptrtoaddr (ptr getelementptr (i8, ptr null, i64 1) to i64)
}

define i64 @ptr2addr2_inttoptr_noas2() {
;
  ret i64 ptrtoaddr (ptr inttoptr (i64 123 to ptr) to i64)
}

define i64 @ptrtoaddr_inttoptr_noas_diff_size1() {
;
  ret i64 ptrtoaddr (ptr inttoptr (i32 -1 to ptr) to i64)
}

define i64 @ptrtoaddr_inttoptr_noas_diff_size2() {
;
  ret i64 ptrtoaddr (ptr inttoptr (i128 -1 to ptr) to i64)
}