1; Tests that invoke <type> @llvm.coro.await.suspend lowers to invoke @helper 2; RUN: opt < %s -passes='module(coro-early),cgscc(coro-split),simplifycfg' -S | FileCheck %s 3 4%Awaiter = type {} 5 6; CHECK: define {{[^@]*}} @f.resume(ptr {{[^%]*}} %[[HDL:.+]]) 7; CHECK: %[[AWAITER:.+]] = getelementptr inbounds %f.Frame, ptr %[[HDL]], i32 0, i32 0 8define void @f() presplitcoroutine personality i32 0 { 9entry: 10 %awaiter = alloca %Awaiter 11 %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null) 12 %size = call i32 @llvm.coro.size.i32() 13 %alloc = call ptr @malloc(i32 %size) 14 %hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc) 15 ; Initial suspend so that all 3 await_suspend invocations are inside f.resume 16 %suspend.init = call i8 @llvm.coro.suspend(token none, i1 false) 17 switch i8 %suspend.init, label %ret [ 18 i8 0, label %step 19 i8 1, label %cleanup 20 ] 21 22; CHECK: invoke void @await_suspend_wrapper_void(ptr %[[AWAITER]], ptr %[[HDL]]) 23; CHECK-NEXT: to label %[[STEP_CONT:[^ ]+]] unwind label %[[PAD:[^ ]+]] 24step: 25 %save = call token @llvm.coro.save(ptr null) 26 invoke void @llvm.coro.await.suspend.void(ptr %awaiter, ptr %hdl, ptr @await_suspend_wrapper_void) 27 to label %step.continue unwind label %pad 28 29; CHECK [[STEP_CONT]]: 30step.continue: 31 %suspend = call i8 @llvm.coro.suspend(token %save, i1 false) 32 switch i8 %suspend, label %ret [ 33 i8 0, label %step1 34 i8 1, label %cleanup 35 ] 36 37; CHECK: %[[RESUME:.+]] = invoke i1 @await_suspend_wrapper_bool(ptr %[[AWAITER]], ptr %[[HDL]]) 38; CHECK-NEXT: to label %[[STEP1_CONT:[^ ]+]] unwind label %[[PAD]] 39step1: 40 %save1 = call token @llvm.coro.save(ptr null) 41 %resume.bool = invoke i1 @llvm.coro.await.suspend.bool(ptr %awaiter, ptr %hdl, ptr @await_suspend_wrapper_bool) 42 to label %step1.continue unwind label %pad 43 44; CHECK: [[STEP1_CONT]]: 45; CHECK-NEXT: br i1 %[[RESUME]], label %{{[^,]+}}, label %[[STEP2:.+]] 46step1.continue: 47 br i1 %resume.bool, label %suspend.cond, label %step2 48 49suspend.cond: 50 %suspend1 = call i8 @llvm.coro.suspend(token %save1, i1 false) 51 switch i8 %suspend1, label %ret [ 52 i8 0, label %step2 53 i8 1, label %cleanup 54 ] 55 56; CHECK: [[STEP2]]: 57; CHECK: %[[NEXT_HDL:.+]] = invoke ptr @await_suspend_wrapper_handle(ptr %[[AWAITER]], ptr %[[HDL]]) 58; CHECK-NEXT: to label %[[STEP2_CONT:[^ ]+]] unwind label %[[PAD]] 59step2: 60 %save2 = call token @llvm.coro.save(ptr null) 61 invoke void @llvm.coro.await.suspend.handle(ptr %awaiter, ptr %hdl, ptr @await_suspend_wrapper_handle) 62 to label %step2.continue unwind label %pad 63 64; CHECK: [[STEP2_CONT]]: 65; CHECK-NEXT: %[[NEXT_RESUME:.+]] = call ptr @llvm.coro.subfn.addr(ptr %[[NEXT_HDL]], i8 0) 66; CHECK-NEXT: musttail call {{.*}} void %[[NEXT_RESUME]](ptr %[[NEXT_HDL]]) 67step2.continue: 68 %suspend2 = call i8 @llvm.coro.suspend(token %save2, i1 false) 69 switch i8 %suspend2, label %ret [ 70 i8 0, label %step3 71 i8 1, label %cleanup 72 ] 73 74step3: 75 br label %cleanup 76 77pad: 78 %lp = landingpad { ptr, i32 } 79 catch ptr null 80 %exn = extractvalue { ptr, i32 } %lp, 0 81 call ptr @__cxa_begin_catch(ptr %exn) 82 call void @__cxa_end_catch() 83 br label %cleanup 84 85cleanup: 86 %mem = call ptr @llvm.coro.free(token %id, ptr %hdl) 87 call void @free(ptr %mem) 88 br label %ret 89 90ret: 91 call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) 92 ret void 93} 94 95; check that we were haven't accidentally went out of @f.resume body 96; CHECK-LABEL: @f.destroy( 97; CHECK-LABEL: @f.cleanup( 98 99declare void @await_suspend_wrapper_void(ptr, ptr) 100declare i1 @await_suspend_wrapper_bool(ptr, ptr) 101declare ptr @await_suspend_wrapper_handle(ptr, ptr) 102 103declare ptr @llvm.coro.free(token, ptr) 104declare i32 @llvm.coro.size.i32() 105declare i8 @llvm.coro.suspend(token, i1) 106declare void @llvm.coro.resume(ptr) 107declare void @llvm.coro.destroy(ptr) 108 109declare token @llvm.coro.id(i32, ptr, ptr, ptr) 110declare i1 @llvm.coro.alloc(token) 111declare ptr @llvm.coro.begin(token, ptr) 112declare void @llvm.coro.await.suspend.void(ptr, ptr, ptr) 113declare i1 @llvm.coro.await.suspend.bool(ptr, ptr, ptr) 114declare void @llvm.coro.await.suspend.handle(ptr, ptr, ptr) 115declare i1 @llvm.coro.end(ptr, i1, token) 116 117declare ptr @__cxa_begin_catch(ptr) 118declare void @use_val(i32) 119declare void @__cxa_end_catch() 120 121declare noalias ptr @malloc(i32) 122declare void @free(ptr) 123