Index: llvm/lib/IR/BasicBlock.cpp =================================================================== --- llvm/lib/IR/BasicBlock.cpp +++ llvm/lib/IR/BasicBlock.cpp @@ -397,7 +397,8 @@ assert(Term->getNumSuccessors() > 0); // Instructions should not be hoisted across exception handling boundaries. - return !Term->isExceptionalTerminator(); + // Also don't hoist across callbr, which produces a value. + return !Term->isExceptionalTerminator() && !isa(Term); } bool BasicBlock::isEntryBlock() const { Index: llvm/test/Transforms/LICM/callbr-crash.ll =================================================================== --- llvm/test/Transforms/LICM/callbr-crash.ll +++ llvm/test/Transforms/LICM/callbr-crash.ll @@ -35,3 +35,27 @@ %phi = phi i32 [ %asmresult1.i.i, %cond.true.i ], [ undef, %for.cond ] ret i32 %phi } + +declare void @use_i32(i32) + +define void @pr64215() { +; CHECK-LABEL: @pr64215( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[X:%.*]] = callbr i32 asm sideeffect "", "=r"() +; CHECK-NEXT: to label [[LOOP_PREHEADER:%.*]] [] +; CHECK: loop.preheader: +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X]], 1 +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: call void @use_i32(i32 [[ADD]]) +; CHECK-NEXT: br label [[LOOP]] +; +entry: + %x = callbr i32 asm sideeffect "", "=r"() + to label %loop [] + +loop: + %add = add i32 %x, 1 + call void @use_i32(i32 %add) + br label %loop +}