Index: llvm/lib/Transforms/IPO/HotColdSplitting.cpp =================================================================== --- llvm/lib/Transforms/IPO/HotColdSplitting.cpp +++ llvm/lib/Transforms/IPO/HotColdSplitting.cpp @@ -117,8 +117,12 @@ if (blockEndsInUnreachable(BB)) { if (auto *CI = dyn_cast_or_null(BB.getTerminator()->getPrevNode())) - if (CI->hasFnAttr(Attribute::NoReturn)) - return false; + if (CI->hasFnAttr(Attribute::NoReturn)) { + if (IntrinsicInst *II = dyn_cast(CI)) + return II->getIntrinsicID() != Intrinsic::longjmp; + CallSite CS(CI); + return !CS.getCalledFunction()->getName().startswith("longjmp"); + } return true; } Index: llvm/test/Transforms/HotColdSplit/noreturn.ll =================================================================== --- llvm/test/Transforms/HotColdSplit/noreturn.ll +++ llvm/test/Transforms/HotColdSplit/noreturn.ll @@ -59,6 +59,24 @@ ret void } +; Outline noreturn calls which are explicitly marked noreturn unless they are longjmp. + +; CHECK-LABEL: define {{.*}}@gap( +; CHECK: gap.cold.1 +define void @gap(i32, %struct.__jmp_buf_tag*) { + %3 = icmp eq i32 %0, 0 + tail call void @_Z10sideeffectv() + br i1 %3, label %5, label %4 + +;