1; RUN: opt < %s -O0 -S | FileCheck %s 2 3target datalayout = "p:64:64:64" 4 5%async.task = type { i64 } 6%async.actor = type { i64 } 7%async.fp = type <{ i32, i32 }> 8 9%async.ctxt = type { ptr, ptr } 10 11@my_other_async_function_fp = external global <{ i32, i32 }> 12declare void @my_other_async_function(ptr %async.ctxt) 13 14@my_async_function_fp = constant <{ i32, i32 }> 15 <{ i32 trunc ( 16 i64 sub ( 17 i64 ptrtoint (ptr @my_async_function to i64), 18 i64 ptrtoint (ptr getelementptr inbounds (<{ i32, i32 }>, ptr @my_async_function_fp, i32 0, i32 1) to i64) 19 ) 20 to i32), 21 i32 32 22}> 23 24declare void @opaque(ptr) 25declare ptr @llvm.coro.async.context.alloc(ptr, ptr) 26declare void @llvm.coro.async.context.dealloc(ptr) 27declare ptr @llvm.coro.async.resume() 28declare token @llvm.coro.id.async(i32, i32, i32, ptr) 29declare ptr @llvm.coro.begin(token, ptr) 30declare i1 @llvm.coro.end.async(ptr, i1, ...) 31declare i1 @llvm.coro.end(ptr, i1, token) 32declare swiftcc void @asyncReturn(ptr) 33declare swiftcc void @asyncSuspend(ptr) 34declare {ptr} @llvm.coro.suspend.async(i32, ptr, ptr, ...) 35 36define swiftcc void @my_async_function.my_other_async_function_fp.apply(ptr %fnPtr, ptr %async.ctxt) { 37 tail call swiftcc void %fnPtr(ptr %async.ctxt) 38 ret void 39} 40 41define ptr @__swift_async_resume_project_context(ptr %ctxt) { 42entry: 43 %resume_ctxt = load ptr, ptr %ctxt, align 8 44 ret ptr %resume_ctxt 45} 46 47 48; CHECK: %my_async_function.Frame = type { i64, [48 x i8], i64, i64, [16 x i8], ptr, i64, ptr } 49; CHECK: define swiftcc void @my_async_function 50; CHECK: [[T0:%.*]] = getelementptr inbounds %my_async_function.Frame, ptr %async.ctx.frameptr, i32 0, i32 3 51; CHECK: [[T1:%.*]] = ptrtoint ptr [[T0]] to i64 52; CHECK: [[T2:%.*]] = add i64 [[T1]], 31 53; CHECK: [[T3:%.*]] = and i64 [[T2]], -32 54; CHECK: [[T4:%.*]] = inttoptr i64 [[T3]] to ptr 55; CHECK: [[FP:%.*]] = getelementptr inbounds %my_async_function.Frame, ptr %async.ctx.frameptr, i32 0, i32 0 56; CHECK: [[T6:%.*]] = ptrtoint ptr [[FP]] to i64 57; CHECK: [[T7:%.*]] = add i64 [[T6]], 63 58; CHECK: [[T8:%.*]] = and i64 [[T7]], -64 59; CHECK: [[T9:%.*]] = inttoptr i64 [[T8]] to ptr 60; CHECK: store i64 2, ptr [[T4]] 61; CHECK: store i64 3, ptr [[T9]] 62 63define swiftcc void @my_async_function(ptr swiftasync %async.ctxt) presplitcoroutine { 64entry: 65 %tmp = alloca i64, align 8 66 %tmp2 = alloca i64, align 16 67 %tmp3 = alloca i64, align 32 68 %tmp4 = alloca i64, align 64 69 70 %id = call token @llvm.coro.id.async(i32 32, i32 16, i32 0, 71 ptr @my_async_function_fp) 72 %hdl = call ptr @llvm.coro.begin(token %id, ptr null) 73 store i64 0, ptr %tmp 74 store i64 1, ptr %tmp2 75 store i64 2, ptr %tmp3 76 store i64 3, ptr %tmp4 77 78 %callee_context = call ptr @llvm.coro.async.context.alloc(ptr null, ptr null) 79 %callee_context.return_to_caller.addr = getelementptr inbounds %async.ctxt, ptr %callee_context, i32 0, i32 1 80 %resume.func_ptr = call ptr @llvm.coro.async.resume() 81 store ptr %resume.func_ptr, ptr %callee_context.return_to_caller.addr 82 83 %res = call {ptr} (i32, ptr, ptr, ...) @llvm.coro.suspend.async(i32 0, 84 ptr %resume.func_ptr, 85 ptr @__swift_async_resume_project_context, 86 ptr @my_async_function.my_other_async_function_fp.apply, 87 ptr @asyncSuspend, ptr %callee_context) 88 call void @opaque(ptr %tmp) 89 call void @opaque(ptr %tmp2) 90 call void @opaque(ptr %tmp3) 91 call void @opaque(ptr %tmp4) 92 call void @llvm.coro.async.context.dealloc(ptr %callee_context) 93 tail call swiftcc void @asyncReturn(ptr %async.ctxt) 94 call i1 (ptr, i1, ...) @llvm.coro.end.async(ptr %hdl, i1 0) 95 unreachable 96} 97