Bug type: crash
Component: DemoteRegToStack
Bug location: llvm/lib/Transforms/Utils/DemoteRegToStack.cpp: llvm::DemoteRegToStack
Issue title: Reg2Mem pass triggered assertion `isa<To>(V al) && "cast<Ty>() argument of incompatible type!"
Labels: crash
llvm:transforms
Reported by: XChy

https://godbolt.org/z/oxW8zbKr6
`opt --passes=reg2mem reduced.ll`
```llvm
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-unknown-linux-gnu"

%struct.__large_struct = type { [100 x i64] }

define fastcc i64 @__se_sys_pselect6() {
  %1 = callbr i64 asm sideeffect "\0A1:\09movq $1,$0\0A .pushsection \22__ex_table\22,\22a\22\0A .balign 4\0A .long (1b) - .\0A .long (${2:l}) - .\0A .long 3 \0A .popsection\0A", "=r,*m,!i,~{dirflag},~{fpsr},~{flags}"(ptr elementtype(%struct.__large_struct) null)
          to label %2 [label %common.ret]

2:                                                ; preds = %0
  %3 = inttoptr i64 %1 to ptr
  %4 = callbr i64 asm sideeffect "\0A1:\09movq $1,$0\0A .pushsection \22__ex_table\22,\22a\22\0A .balign 4\0A .long (1b) - .\0A .long (${2:l}) - .\0A .long 3 \0A .popsection\0A", "=r,*m,!i,~{dirflag},~{fpsr},~{flags}"(ptr elementtype(%struct.__large_struct) null)
          to label %common.ret [label %common.ret]

common.ret:                                       ; preds = %2, %2, %0
  ret i64 0
}
```


Fix patch:
commit fdaad738753cde2bba6480c2ee5d1e9fb45064b9
Author: XChy <xxs_chy@outlook.com>
Date:   Thu May 16 20:13:39 2024 +0800

    [Reg2Mem] Handle CallBr instructions (#90953)
    
    Fixes #90900

diff --git a/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp b/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
index b2a88eadd3de..f03de2f25a41 100644
--- a/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
+++ b/llvm/lib/Transforms/Utils/DemoteRegToStack.cpp
@@ -50,6 +50,15 @@ AllocaInst *llvm::DemoteRegToStack(Instruction &I, bool VolatileLoads,
       assert(BB && "Unable to split critical edge.");
       (void)BB;
     }
+  } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) {
+    for (int i = 0; i < CBI->getNumSuccessors(); i++) {
+      auto *Succ = CBI->getSuccessor(i);
+      if (!Succ->getSinglePredecessor()) {
+        assert(isCriticalEdge(II, i) && "Expected a critical edge!");
+        BasicBlock *BB = SplitCriticalEdge(II, i);
+        assert(BB && "Unable to split critical edge.");
+      }
+    }
   }
 
   // Change all of the users of the instruction to read from the stack slot.
@@ -102,9 +111,14 @@ AllocaInst *llvm::DemoteRegToStack(Instruction &I, bool VolatileLoads,
         new StoreInst(&I, Slot, Handler->getFirstInsertionPt());
       return Slot;
     }
+  } else if (InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
+    InsertPt = II->getNormalDest()->getFirstInsertionPt();
+  } else if (CallBrInst *CBI = dyn_cast<CallBrInst>(&I)) {
+    for (BasicBlock *Succ : successors(CBI))
+      new StoreInst(CBI, Slot, Succ->getFirstInsertionPt());
+    return Slot;
   } else {
-    InvokeInst &II = cast<InvokeInst>(I);
-    InsertPt = II.getNormalDest()->getFirstInsertionPt();
+    llvm_unreachable("Unsupported terminator for Reg2Mem");
   }
 
   new StoreInst(&I, Slot, InsertPt);


Regression tests:
file: llvm/test/Transforms/Reg2Mem/callbr-crash.ll
commands: opt -passes=reg2mem -S < %s
tests: test_name: <module>
test_body: 
define void @crash() {
;
entry:
  %a = callbr i64 asm "", "=r,r,!i"(i64 0)
  to label %then [label %else]

then:
  %b = inttoptr i64 %a to ptr
  br label %else

else:
  ret void
}