Index: lib/IR/Verifier.cpp =================================================================== --- lib/IR/Verifier.cpp +++ lib/IR/Verifier.cpp @@ -3653,11 +3653,13 @@ Assert( !F->isIntrinsic() || isa(I) || F->getIntrinsicID() == Intrinsic::donothing || + F->getIntrinsicID() == Intrinsic::coro_resume || + F->getIntrinsicID() == Intrinsic::coro_destroy || F->getIntrinsicID() == Intrinsic::experimental_patchpoint_void || F->getIntrinsicID() == Intrinsic::experimental_patchpoint_i64 || F->getIntrinsicID() == Intrinsic::experimental_gc_statepoint, - "Cannot invoke an intrinsic other than donothing, patchpoint or " - "statepoint", + "Cannot invoke an intrinsic other than donothing, patchpoint, " + "statepoint, coro_resume or coro_destroy", &I); Assert(F->getParent() == M, "Referencing function in another module!", &I, M, F, F->getParent()); Index: lib/Transforms/Coroutines/CoroEarly.cpp =================================================================== --- lib/Transforms/Coroutines/CoroEarly.cpp +++ lib/Transforms/Coroutines/CoroEarly.cpp @@ -49,18 +49,21 @@ bool Changed = false; for (auto IB = inst_begin(F), IE = inst_end(F); IB != IE;) { Instruction &I = *IB++; - if (auto *II = dyn_cast(&I)) { - switch (II->getIntrinsicID()) { - default: + if (auto CS = CallSite(&I)) { + if (Function *F = CS.getCalledFunction()) { + switch (F->getIntrinsicID()) { + default: + continue; + case Intrinsic::coro_resume: + lowerResumeOrDestroy(CS, CoroSubFnInst::ResumeIndex); + break; + case Intrinsic::coro_destroy: + lowerResumeOrDestroy(CS, CoroSubFnInst::DestroyIndex); + break; + } + Changed = true; continue; - case Intrinsic::coro_resume: - lowerResumeOrDestroy(II, CoroSubFnInst::ResumeIndex); - break; - case Intrinsic::coro_destroy: - lowerResumeOrDestroy(II, CoroSubFnInst::DestroyIndex); - break; } - Changed = true; } } return Changed; Index: test/Transforms/Coroutines/coro-early.ll =================================================================== --- test/Transforms/Coroutines/coro-early.ll +++ test/Transforms/Coroutines/coro-early.ll @@ -20,5 +20,22 @@ ; CHECK-NEXT: ret void } +; CHECK-LABEL: @eh +define void @eh(i8* %hdl) personality i8* null { +; CHECK-NEXT: entry +entry: +; CHECK-NEXT: %0 = call i8* @llvm.coro.subfn.addr(i8* %hdl, i8 0) +; CHECK-NEXT: %1 = bitcast i8* %0 to void (i8*)* +; CHECK-NEXT: invoke fastcc void %1(i8* %hdl) + invoke void @llvm.coro.resume(i8* %hdl) + to label %cont unwind label %ehcleanup +cont: + ret void + +ehcleanup: + %0 = cleanuppad within none [] + cleanupret from %0 unwind to caller +} + declare void @llvm.coro.resume(i8*) declare void @llvm.coro.destroy(i8*)