brintos

brintos / llvm-project-archived public Read only

0
0
Text · 26.5 KiB · f94c6c1 Raw
575 lines · plain
1; RUN: opt < %s -passes='default<O2>' -S | FileCheck --check-prefixes=CHECK %s2; RUN: opt < %s -O0 -S | FileCheck --check-prefixes=CHECK-O0 %s3target 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; The async callee.12@my_other_async_function_fp = external global <{ i32, i32 }>13declare void @my_other_async_function(ptr %async.ctxt)14 15; The current async function (the caller).16; This struct describes an async function. The first field is the17; relative offset to the async function implementation, the second field is the18; size needed for the async context of the current async function.19 20@my_async_function_fp = constant <{ i32, i32 }>21  <{ i32 trunc ( ; Relative pointer to async function22       i64 sub (23         i64 ptrtoint (ptr @my_async_function to i64),24         i64 ptrtoint (ptr getelementptr inbounds (<{ i32, i32 }>, ptr @my_async_function_fp, i32 0, i32 1) to i64)25       )26     to i32),27     i32 128    ; Initial async context size without space for frame28}>29@my_async_function_pa_fp = constant <{ i32, i32 }>30  <{ i32 trunc (31       i64 sub (32         i64 ptrtoint (ptr @my_async_function_pa to i64),33         i64 ptrtoint (ptr getelementptr inbounds (<{ i32, i32 }>, ptr @my_async_function_pa_fp, i32 0, i32 1) to i64)34       )35     to i32),36     i32 837}>38 39; Function that implements the dispatch to the callee function.40define swiftcc void @my_async_function.my_other_async_function_fp.apply(ptr %fnPtr, ptr %async.ctxt, ptr %task, ptr %actor) {41  tail call swiftcc void %fnPtr(ptr %async.ctxt, ptr %task, ptr %actor)42  ret void43}44 45declare void @some_user(i64)46declare void @some_may_write(ptr)47 48define ptr @__swift_async_resume_project_context(ptr %ctxt) {49entry:50  %resume_ctxt = load ptr, ptr %ctxt, align 851  ret ptr %resume_ctxt52}53 54define ptr @resume_context_projection(ptr %ctxt) {55entry:56  %resume_ctxt = load ptr, ptr %ctxt, align 857  ret ptr %resume_ctxt58}59 60 61define swiftcc void @my_async_function(ptr swiftasync %async.ctxt, ptr %task, ptr %actor) presplitcoroutine !dbg !1 {62entry:63  %tmp = alloca { i64, i64 }, align 864  %vector = alloca <4 x double>, align 1665  %proj.1 = getelementptr inbounds { i64, i64 }, ptr %tmp, i64 0, i32 066  %proj.2 = getelementptr inbounds { i64, i64 }, ptr %tmp, i64 0, i32 167 68  %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,69          ptr @my_async_function_fp)70  %hdl = call ptr @llvm.coro.begin(token %id, ptr null)71  store i64 0, ptr %proj.1, align 872  store i64 1, ptr %proj.2, align 873  call void @some_may_write(ptr %proj.1)74 75	; Begin lowering: apply %my_other_async_function(%args...)76 77  ; setup callee context78  %callee_context = call ptr @llvm.coro.async.context.alloc(ptr %task, ptr @my_other_async_function_fp)79  ; store arguments ...80  ; ... (omitted)81 82  ; store the return continuation83  %callee_context.return_to_caller.addr = getelementptr inbounds %async.ctxt, ptr %callee_context, i32 0, i32 184  %resume.func_ptr = call ptr @llvm.coro.async.resume()85  store ptr %resume.func_ptr, ptr %callee_context.return_to_caller.addr86 87  ; store caller context into callee context88  store ptr %async.ctxt, ptr %callee_context89  %vector_spill = load <4 x double>, ptr %vector, align 1690  %res = call {ptr, ptr, ptr} (i32, ptr, ptr, ...) @llvm.coro.suspend.async(i32 0,91                                                  ptr %resume.func_ptr,92                                                  ptr @__swift_async_resume_project_context,93                                                  ptr @my_async_function.my_other_async_function_fp.apply,94                                                  ptr @asyncSuspend, ptr %callee_context, ptr %task, ptr %actor), !dbg !595 96  call void @llvm.coro.async.context.dealloc(ptr %callee_context)97  %continuation_task_arg = extractvalue {ptr, ptr, ptr} %res, 198  %val = load i64, ptr %proj.199  call void @some_user(i64 %val)100  %val.2 = load i64, ptr %proj.2101  call void @some_user(i64 %val.2)102  store <4 x double> %vector_spill, ptr %vector, align 16103  tail call swiftcc void @asyncReturn(ptr %async.ctxt, ptr %continuation_task_arg, ptr %actor)104  call void (ptr, i1, ...) @llvm.coro.end.async(ptr %hdl, i1 0)105  unreachable106}107 108define void @my_async_function_pa(ptr %ctxt, ptr %task, ptr %actor) {109  call void @llvm.coro.async.size.replace(ptr @my_async_function_pa_fp, ptr @my_async_function_fp)110  call swiftcc void @my_async_function(ptr %ctxt, ptr %task, ptr %actor)111  ret void112}113 114; Make sure we update the async function pointer115; CHECK: @my_async_function_fp = constant <{ i32, i32 }> <{ {{.*}}, i32 176 }116; CHECK: @my_async_function_pa_fp = constant <{ i32, i32 }> <{ {{.*}}, i32 176 }117; CHECK: @my_async_function2_fp = constant <{ i32, i32 }> <{ {{.*}}, i32 176 }118 119; CHECK-LABEL: define swiftcc void @my_async_function(ptr swiftasync initializes((152, 160)) %async.ctxt, ptr %task, ptr %actor)120; CHECK-O0-LABEL: define swiftcc void @my_async_function(ptr swiftasync %async.ctxt, ptr %task, ptr %actor)121; CHECK-SAME: !dbg ![[SP1:[0-9]+]] {122; CHECK: coro.return:123; CHECK:   [[FRAMEPTR:%.*]] = getelementptr inbounds nuw i8, ptr %async.ctxt, i64 128124; CHECK:   [[ACTOR_SPILL_ADDR:%.*]] = getelementptr inbounds nuw i8, ptr %async.ctxt, i64 152125; CHECK:   store ptr %actor, ptr [[ACTOR_SPILL_ADDR]]126; CHECK:   [[ADDR1:%.*]]  = getelementptr inbounds nuw i8, ptr %async.ctxt, i64 144127; CHECK:   store ptr %async.ctxt, ptr [[ADDR1]]128; CHECK:   [[ALLOCA_PRJ2:%.*]] = getelementptr inbounds nuw i8, ptr %async.ctxt, i64 136129; CHECK:   store i64 0, ptr [[FRAMEPTR]]130; CHECK:   store i64 1, ptr [[ALLOCA_PRJ2]]131; CHECK:   tail call void @some_may_write(ptr nonnull [[FRAMEPTR]])132; CHECK:   [[CALLEE_CTXT:%.*]] = tail call ptr @llvm.coro.async.context.alloc(ptr %task, ptr nonnull @my_other_async_function_fp)133; CHECK:   [[CALLEE_CTXT_SPILL:%.*]] = getelementptr inbounds nuw i8, ptr %async.ctxt, i64 160134; CHECK:   store ptr [[CALLEE_CTXT]], ptr [[CALLEE_CTXT_SPILL]]135; CHECK:   [[TYPED_RETURN_TO_CALLER_ADDR:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLEE_CTXT]], i64 8136; CHECK:   store ptr @my_async_functionTQ0_, ptr [[TYPED_RETURN_TO_CALLER_ADDR]]137; CHECK:   store ptr %async.ctxt, ptr [[CALLEE_CTXT]]138; Make sure the spill is underaligned to the max context alignment (16).139; CHECK-O0:   [[VECTOR_SPILL:%.*]] = load <4 x double>, ptr {{.*}}140; CHECK-O0:   [[VECTOR_SPILL_ADDR:%.*]] = getelementptr inbounds %my_async_function.Frame, ptr {{.*}}, i32 0, i32 1141; CHECK-O0:   store <4 x double> [[VECTOR_SPILL]], ptr [[VECTOR_SPILL_ADDR]], align 16142; CHECK:   tail call swiftcc void @asyncSuspend(ptr nonnull [[CALLEE_CTXT]], ptr %task, ptr %actor)143; CHECK:   ret void144; CHECK: }145 146; CHECK-LABEL: define internal swiftcc void @my_async_functionTQ0_(ptr readonly swiftasync captures(none) %0, ptr %1, ptr readnone captures(none) %2)147; CHECK-O0-LABEL: define internal swiftcc void @my_async_functionTQ0_(ptr swiftasync %0, ptr %1, ptr %2)148; CHECK-SAME: !dbg ![[SP2:[0-9]+]] {149; CHECK: entryresume.0:150; CHECK:   [[CALLER_CONTEXT:%.*]] = load ptr, ptr %0151; CHECK:   [[FRAME_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLER_CONTEXT]], i64 128152; CHECK-O0:   [[VECTOR_SPILL_ADDR:%.*]] = getelementptr inbounds %my_async_function.Frame, ptr {{.*}}, i32 0, i32 1153; CHECK-O0:   load <4 x double>, ptr [[VECTOR_SPILL_ADDR]], align 16154; CHECK:   [[CALLEE_CTXT_SPILL_ADDR:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLER_CONTEXT]], i64 160155; CHECK:   [[CALLEE_CTXT_RELOAD:%.*]] = load ptr, ptr [[CALLEE_CTXT_SPILL_ADDR]]156; CHECK:   [[ACTOR_RELOAD_ADDR:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLER_CONTEXT]], i64 152157; CHECK:   [[ACTOR_RELOAD:%.*]] = load ptr, ptr [[ACTOR_RELOAD_ADDR]]158; CHECK:   [[ADDR1:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLER_CONTEXT]], i64 144159; CHECK:   [[ASYNC_CTXT_RELOAD:%.*]] = load ptr, ptr [[ADDR1]]160; CHECK:   [[ALLOCA_PRJ2:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLER_CONTEXT]], i64 136161; CHECK:   tail call void @llvm.coro.async.context.dealloc(ptr nonnull [[CALLEE_CTXT_RELOAD]])162; CHECK:   [[VAL1:%.*]] = load i64, ptr [[FRAME_PTR]]163; CHECK:   tail call void @some_user(i64 [[VAL1]])164; CHECK:   [[VAL2:%.*]] = load i64, ptr [[ALLOCA_PRJ2]]165; CHECK:   tail call void @some_user(i64 [[VAL2]])166; CHECK:   tail call swiftcc void @asyncReturn(ptr [[ASYNC_CTXT_RELOAD]], ptr %1, ptr [[ACTOR_RELOAD]])167; CHECK:   ret void168; CHECK: }169 170@my_async_function2_fp = constant <{ i32, i32 }>171  <{ i32 trunc ( ; Relative pointer to async function172       i64 sub (173         i64 ptrtoint (ptr @my_async_function2 to i64),174         i64 ptrtoint (ptr getelementptr inbounds (<{ i32, i32 }>, ptr @my_async_function2_fp, i32 0, i32 1) to i64)175       )176     to i32),177     i32 128    ; Initial async context size without space for frame178  }>179 180define swiftcc void @my_async_function2(ptr %task, ptr %actor, ptr %async.ctxt) presplitcoroutine "frame-pointer"="all" !dbg !6 {181entry:182 183  %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 2, ptr @my_async_function2_fp)184  %hdl = call ptr @llvm.coro.begin(token %id, ptr null)185  ; setup callee context186  %callee_context = call ptr @llvm.coro.async.context.alloc(ptr %task, ptr @my_other_async_function_fp)187 188  %callee_context.return_to_caller.addr = getelementptr inbounds %async.ctxt, ptr %callee_context, i32 0, i32 1189  %resume.func_ptr = call ptr @llvm.coro.async.resume()190  store ptr %resume.func_ptr, ptr %callee_context.return_to_caller.addr191  store ptr %async.ctxt, ptr %callee_context192  %res = call {ptr, ptr, ptr} (i32, ptr, ptr, ...) @llvm.coro.suspend.async(i32 2,193                                                  ptr %resume.func_ptr,194                                                  ptr @resume_context_projection,195                                                  ptr @my_async_function.my_other_async_function_fp.apply,196                                                  ptr @asyncSuspend, ptr %callee_context, ptr %task, ptr %actor), !dbg !9197 198  %continuation_task_arg = extractvalue {ptr, ptr, ptr} %res, 0199 200  %callee_context.return_to_caller.addr.1 = getelementptr inbounds %async.ctxt, ptr %callee_context, i32 0, i32 1201  %resume.func_ptr.1 = call ptr @llvm.coro.async.resume()202  store ptr %resume.func_ptr.1, ptr %callee_context.return_to_caller.addr.1203  store ptr %async.ctxt, ptr %callee_context204  %res.2 = call {ptr, ptr, ptr} (i32, ptr, ptr, ...) @llvm.coro.suspend.async(i32 0,205                                                  ptr %resume.func_ptr.1,206                                                  ptr @resume_context_projection,207                                                  ptr @my_async_function.my_other_async_function_fp.apply,208                                                  ptr @asyncSuspend, ptr %callee_context, ptr %task, ptr %actor)209 210  call void @llvm.coro.async.context.dealloc(ptr %callee_context)211  %continuation_actor_arg = extractvalue {ptr, ptr, ptr} %res.2, 1212 213  tail call swiftcc void @asyncReturn(ptr %async.ctxt, ptr %continuation_task_arg, ptr %continuation_actor_arg)214  call void @llvm.coro.end(ptr %hdl, i1 0, token none)215  unreachable216}217 218; CHECK-LABEL: define swiftcc void @my_async_function2(ptr %task, ptr %actor, ptr %async.ctxt)219; CHECK-SAME: #[[FRAMEPOINTER:[0-9]+]]220; CHECK-SAME: !dbg ![[SP3:[0-9]+]]221; CHECK: store ptr %async.ctxt,222; CHECK: store ptr %actor,223; CHECK: store ptr %task,224; CHECK: [[CALLEE_CTXT:%.*]] =  tail call ptr @llvm.coro.async.context.alloc(225; CHECK: store ptr [[CALLEE_CTXT]],226; CHECK: store ptr @my_async_function2.resume.0,227; CHECK: store ptr %async.ctxt,228; CHECK: tail call swiftcc void @asyncSuspend(ptr nonnull [[CALLEE_CTXT]], ptr %task, ptr %actor)229; CHECK: ret void230 231; CHECK-LABEL: define internal swiftcc void @my_async_function2.resume.0(ptr %0, ptr readnone captures(none) %1, ptr readonly captures(none) %2)232; CHECK-SAME: #[[FRAMEPOINTER]]233; CHECK-SAME: !dbg ![[SP4:[0-9]+]]234; CHECK: [[CALLEE_CTXT:%.*]] = load ptr, ptr %2235; CHECK: [[CALLEE_CTXT_SPILL_ADDR:%.*]] = getelementptr inbounds nuw i8, ptr [[CALLEE_CTXT]], i64 152236; CHECK: store ptr @my_async_function2.resume.1,237; CHECK: [[CALLLE_CTXT_RELOAD:%.*]] = load ptr, ptr [[CALLEE_CTXT_SPILL_ADDR]]238; CHECK: tail call swiftcc void @asyncSuspend(ptr [[CALLEE_CTXT_RELOAD]]239; CHECK: ret void240 241; CHECK-LABEL: define internal swiftcc void @my_async_function2.resume.1(ptr readonly captures(none) %0, ptr %1, ptr readnone captures(none) %2)242; CHECK-SAME: #[[FRAMEPOINTER]]243; CHECK: tail call swiftcc void @asyncReturn({{.*}}%1)244; CHECK: ret void245 246define swiftcc void @top_level_caller(ptr %ctxt, ptr %task, ptr %actor) {247  %prepare = call ptr @llvm.coro.prepare.async(ptr @my_async_function)248  call swiftcc void %prepare(ptr %ctxt, ptr %task, ptr %actor)249  ret void250}251 252; CHECK-LABEL: define swiftcc void @top_level_caller(ptr initializes((152, 160)) %ctxt, ptr %task, ptr %actor)253; CHECK: store ptr @my_async_functionTQ0_254; CHECK: store ptr %ctxt255; CHECK: tail call swiftcc void @asyncSuspend256; CHECK: ret void257 258@dont_crash_on_cf_fp = constant <{ i32, i32 }>259  <{ i32 trunc ( ; Relative pointer to async function260       i64 sub (261         i64 ptrtoint (ptr @my_async_function to i64),262         i64 ptrtoint (ptr getelementptr inbounds (<{ i32, i32 }>, ptr @my_async_function_fp, i32 0, i32 1) to i64)263       )264     to i32),265     i32 128    ; Initial async context size without space for frame266}>267 268 269define swiftcc void @dont_crash_on_cf_dispatch(ptr %fnPtr, ptr %async.ctxt, ptr %task, ptr %actor) {270  %isNull = icmp eq ptr %task, null271  br i1 %isNull, label %is_null, label %is_not_null272 273is_null:274  ret void275 276is_not_null:277  tail call swiftcc void %fnPtr(ptr %async.ctxt, ptr %task, ptr %actor)278  ret void279}280 281define swiftcc void @dont_crash_on_cf(ptr %async.ctxt, ptr %task, ptr %actor) presplitcoroutine  {282entry:283  %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,284          ptr @dont_crash_on_cf_fp)285  %hdl = call ptr @llvm.coro.begin(token %id, ptr null)286  %callee_context = call ptr @llvm.coro.async.context.alloc(ptr %task, ptr @my_other_async_function_fp)287  %callee_context.return_to_caller.addr = getelementptr inbounds %async.ctxt, ptr %callee_context, i32 0, i32 1288  %resume.func_ptr = call ptr @llvm.coro.async.resume()289  store ptr %resume.func_ptr, ptr %callee_context.return_to_caller.addr290  store ptr %async.ctxt, ptr %callee_context291  %res = call {ptr, ptr, ptr} (i32, ptr, ptr, ...) @llvm.coro.suspend.async(i32 0,292                                                  ptr %resume.func_ptr,293                                                  ptr @resume_context_projection,294                                                  ptr @dont_crash_on_cf_dispatch,295                                                  ptr @asyncSuspend, ptr %callee_context, ptr %task, ptr %actor)296 297  call void @llvm.coro.async.context.dealloc(ptr %callee_context)298  %continuation_task_arg = extractvalue {ptr, ptr, ptr} %res, 1299  tail call swiftcc void @asyncReturn(ptr %async.ctxt, ptr %continuation_task_arg, ptr %actor)300  call void (ptr, i1, ...) @llvm.coro.end.async(ptr %hdl, i1 0)301  unreachable302}303 304@multiple_coro_end_async_fp = constant <{ i32, i32 }>305  <{ i32 trunc ( ; Relative pointer to async function306       i64 sub (307         i64 ptrtoint (ptr @multiple_coro_end_async to i64),308         i64 ptrtoint (ptr getelementptr inbounds (<{ i32, i32 }>, ptr @multiple_coro_end_async_fp, i32 0, i32 1) to i64)309       )310     to i32),311     i32 128    ; Initial async context size without space for frame312}>313 314define swiftcc void @must_tail_call_return(ptr %async.ctxt, ptr %task, ptr %actor) {315  musttail call swiftcc void @asyncReturn(ptr %async.ctxt, ptr %task, ptr %actor)316  ret void317}318 319define swiftcc void @multiple_coro_end_async(ptr %async.ctxt, ptr %task, ptr %actor) presplitcoroutine {320entry:321  %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,322          ptr @dont_crash_on_cf_fp)323  %hdl = call ptr @llvm.coro.begin(token %id, ptr null)324  %callee_context = call ptr @llvm.coro.async.context.alloc(ptr %task, ptr @my_other_async_function_fp)325  %callee_context.return_to_caller.addr = getelementptr inbounds %async.ctxt, ptr %callee_context, i32 0, i32 1326  %resume.func_ptr = call ptr @llvm.coro.async.resume()327  store ptr %resume.func_ptr, ptr %callee_context.return_to_caller.addr328  store ptr %async.ctxt, ptr %callee_context329  %res = call {ptr, ptr, ptr} (i32, ptr, ptr, ...) @llvm.coro.suspend.async(i32 0,330                                                  ptr %resume.func_ptr,331                                                  ptr @resume_context_projection,332                                                  ptr @dont_crash_on_cf_dispatch,333                                                  ptr @asyncSuspend, ptr %callee_context, ptr %task, ptr %actor)334 335  call void @llvm.coro.async.context.dealloc(ptr %callee_context)336  %continuation_task_arg = extractvalue {ptr, ptr, ptr} %res, 1337  %eq = icmp eq ptr %continuation_task_arg, null338  br i1 %eq, label %is_equal, label %is_not_equal339 340is_equal:341  tail call swiftcc void @asyncReturn(ptr %async.ctxt, ptr %continuation_task_arg, ptr %actor)342  call void (ptr, i1, ...) @llvm.coro.end.async(ptr %hdl, i1 0)343  unreachable344 345is_not_equal:346  call void (ptr, i1, ...) @llvm.coro.end.async(347                           ptr %hdl, i1 0,348                           ptr @must_tail_call_return,349                           ptr %async.ctxt, ptr %continuation_task_arg, ptr null)350  unreachable351}352 353; CHECK-LABEL: define internal swiftcc void @multiple_coro_end_async.resume.0(354; CHECK: musttail call swiftcc void @asyncReturn(355; CHECK: ret void356 357@polymorphic_suspend_return_fp = constant <{ i32, i32 }>358  <{ i32 trunc ( ; Relative pointer to async function359       i64 sub (360         i64 ptrtoint (ptr @polymorphic_suspend_return to i64),361         i64 ptrtoint (ptr getelementptr inbounds (<{ i32, i32 }>, ptr @polymorphic_suspend_return_fp, i32 0, i32 1) to i64)362       )363     to i32),364     i32 64    ; Initial async context size without space for frame365}>366 367define swiftcc void @polymorphic_suspend_return(ptr swiftasync %async.ctxt, ptr %task, ptr %actor) presplitcoroutine {368entry:369  %tmp = alloca { i64, i64 }, align 8370  %proj.1 = getelementptr inbounds { i64, i64 }, ptr %tmp, i64 0, i32 0371  %proj.2 = getelementptr inbounds { i64, i64 }, ptr %tmp, i64 0, i32 1372 373  %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,374          ptr @polymorphic_suspend_return_fp)375  %hdl = call ptr @llvm.coro.begin(token %id, ptr null)376  store i64 0, ptr %proj.1, align 8377  store i64 1, ptr %proj.2, align 8378  call void @some_may_write(ptr %proj.1)379 380	; Begin lowering: apply %my_other_async_function(%args...)381 382  ; setup callee context383  %callee_context = call ptr @llvm.coro.async.context.alloc(ptr %task, ptr @my_other_async_function_fp)384  ; store arguments ...385  ; ... (omitted)386 387  ; store the return continuation388  %callee_context.return_to_caller.addr = getelementptr inbounds %async.ctxt, ptr %callee_context, i32 0, i32 1389  %resume.func_ptr = call ptr @llvm.coro.async.resume()390  store ptr %resume.func_ptr, ptr %callee_context.return_to_caller.addr391 392  ; store caller context into callee context393  store ptr %async.ctxt, ptr %callee_context394  %res = call {ptr, ptr, ptr, ptr} (i32, ptr, ptr, ...)395         @llvm.coro.suspend.async.sl_p0i8p0i8p0i8p0i8s(i32 256, ;; swiftasync at 0 and swiftself at 1 in resume function396                                                 ptr %resume.func_ptr,397                                                 ptr @resume_context_projection,398                                                 ptr @my_async_function.my_other_async_function_fp.apply,399                                                 ptr @asyncSuspend, ptr %callee_context, ptr %task, ptr %actor)400 401  call void @llvm.coro.async.context.dealloc(ptr %callee_context)402  %continuation_task_arg = extractvalue {ptr, ptr, ptr, ptr} %res, 3403  %val = load i64, ptr %proj.1404  call void @some_user(i64 %val)405  %val.2 = load i64, ptr %proj.2406  call void @some_user(i64 %val.2)407 408  tail call swiftcc void @asyncReturn(ptr %async.ctxt, ptr %continuation_task_arg, ptr %actor)409  call void (ptr, i1, ...) @llvm.coro.end.async(ptr %hdl, i1 0)410  unreachable411}412 413; CHECK-LABEL: define swiftcc void @polymorphic_suspend_return(ptr swiftasync initializes((152, 160)) %async.ctxt, ptr %task, ptr %actor)414; CHECK-LABEL: define internal swiftcc void @polymorphic_suspend_return.resume.0(ptr {{.*}}swiftasync{{.*}} %0, ptr {{.*}}swiftself{{.*}} %1, ptr {{.*}}%2, ptr {{.*}}%3)415; CHECK: }416 417@no_coro_suspend_fp = constant <{ i32, i32 }>418  <{ i32 trunc ( ; Relative pointer to async function419       i64 sub (420         i64 ptrtoint (ptr @no_coro_suspend to i64),421         i64 ptrtoint (ptr getelementptr inbounds (<{ i32, i32 }>, ptr @no_coro_suspend_fp, i32 0, i32 1) to i64)422       )423     to i32),424     i32 128    ; Initial async context size without space for frame425}>426 427define swiftcc void @no_coro_suspend(ptr %async.ctx) presplitcoroutine {428entry:429  %some_alloca = alloca i64430  %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,431          ptr @no_coro_suspend_fp)432  %hdl = call ptr @llvm.coro.begin(token %id, ptr null)433  call void @some_may_write(ptr %some_alloca)434  call void (ptr, i1, ...) @llvm.coro.end.async(ptr %hdl, i1 0)435  unreachable436}437 438; CHECK-LABEL: define swiftcc void @no_coro_suspend439; CHECK:   [[ALLOCA:%.*]] = alloca i64440; CHECK:   call void @some_may_write(ptr {{.*}}[[ALLOCA]])441 442@no_coro_suspend_swifterror_fp = constant <{ i32, i32 }>443  <{ i32 trunc ( ; Relative pointer to async function444       i64 sub (445         i64 ptrtoint (ptr @no_coro_suspend_swifterror to i64),446         i64 ptrtoint (ptr getelementptr inbounds (<{ i32, i32 }>, ptr @no_coro_suspend_swifterror_fp, i32 0, i32 1) to i64)447       )448     to i32),449     i32 128    ; Initial async context size without space for frame450}>451 452declare void @do_with_swifterror(ptr swifterror)453 454define swiftcc void @no_coro_suspend_swifterror(ptr %async.ctx) presplitcoroutine {455entry:456  %some_alloca = alloca swifterror ptr457  %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,458          ptr @no_coro_suspend_swifterror_fp)459  %hdl = call ptr @llvm.coro.begin(token %id, ptr null)460  store ptr null, ptr %some_alloca, align 8461  call void @do_with_swifterror(ptr swifterror %some_alloca)462  call void (ptr, i1, ...) @llvm.coro.end.async(ptr %hdl, i1 0)463  unreachable464}465 466 ; CHECK-LABEL: define swiftcc void @no_coro_suspend_swifterror467 ; CHECK:  [[ALLOCA:%.*]] = alloca swifterror ptr468 ; CHECK:   store ptr null, ptr [[ALLOCA]]469 ; CHECK:   call void @do_with_swifterror(ptr {{.*}}swifterror{{.*}} [[ALLOCA]])470 471@undefined_coro_async_resume_fp = constant <{ i32, i32 }>472  <{ i32 trunc (473       i64 sub (474         i64 ptrtoint (ptr @undefined_coro_async_resume to i64),475         i64 ptrtoint (ptr getelementptr inbounds (<{ i32, i32 }>, ptr @undefined_coro_async_resume_fp, i32 0, i32 1) to i64)476       )477     to i32),478     i32 24479}>480 481declare void @crash()482declare void @use(ptr)483 484define swiftcc void @undefined_coro_async_resume(ptr %async.ctx) presplitcoroutine {485entry:486  %id = call token @llvm.coro.id.async(i32 24, i32 16, i32 0, ptr @undefined_coro_async_resume_fp)487  %hdl = call ptr @llvm.coro.begin(token %id, ptr null)488  %undefined_resume_pointer = call ptr @llvm.coro.async.resume()489  call void @use(ptr %undefined_resume_pointer)490  call void @crash()491  call void (ptr, i1, ...) @llvm.coro.end.async(ptr %hdl, i1 false)492  unreachable493}494; CHECK-LABEL: define swiftcc void @undefined_coro_async_resume495; CHECK-NOT: @llvm.coro.async.resume496; CHECK: call void @use(ptr null)497; CHECK: ret498 499@simpleFuncTu = global <{i32, i32}> <{500  i32 trunc (i64 sub (i64 ptrtoint (ptr @simpleFunc to i64),501             i64 ptrtoint (ptr @simpleFuncTu to i64)) to i32), i32 16 }>502 503define swifttailcc void @simpleFunc(ptr swiftasync %0) presplitcoroutine {504entry:505  %1 = alloca ptr, align 8506  %2 = call token @llvm.coro.id.async(i32 16, i32 16, i32 0, ptr @simpleFuncTu)507  %3 = call ptr @llvm.coro.begin(token %2, ptr null)508  store ptr %0, ptr %1, align 8509  %4 = load ptr, ptr %1, align 8510  %5 = getelementptr inbounds <{ ptr, ptr }>, ptr %4, i32 0, i32 1511  %6 = load ptr, ptr %5, align 8512  %7 = load ptr, ptr %1, align 8513  call void (ptr, i1, ...) @llvm.coro.end.async(ptr %3, i1 false, ptr @simpleFunc.0, ptr %6, ptr %7)514  unreachable515}516 517; CHECK-LABEL: define swifttailcc void @simpleFunc(ptr swiftasync %0) {518; CHECK-NOT: define519; CHECK:  [[RESUME:%.*]] = load ptr520; CHECK:  musttail call swifttailcc void [[RESUME]]521 522define internal swifttailcc void @simpleFunc.0(ptr %0, ptr %1) alwaysinline {523entry:524  musttail call swifttailcc void %0(ptr swiftasync %1)525  ret void526}527 528declare { ptr, ptr, ptr, ptr } @llvm.coro.suspend.async.sl_p0i8p0i8p0i8p0i8s(i32, ptr, ptr, ...)529declare ptr @llvm.coro.prepare.async(ptr)530declare token @llvm.coro.id.async(i32, i32, i32, ptr)531declare ptr @llvm.coro.begin(token, ptr)532declare void @llvm.coro.end.async(ptr, i1, ...)533declare void @llvm.coro.end(ptr, i1, token)534declare {ptr, ptr, ptr} @llvm.coro.suspend.async(i32, ptr, ptr, ...)535declare ptr @llvm.coro.async.context.alloc(ptr, ptr)536declare void @llvm.coro.async.context.dealloc(ptr)537declare swiftcc void @asyncReturn(ptr, ptr, ptr)538declare swiftcc void @asyncSuspend(ptr, ptr, ptr)539declare ptr @llvm.coro.async.resume()540declare void @llvm.coro.async.size.replace(ptr, ptr)541declare ptr @hide(ptr)542 543!llvm.dbg.cu = !{!2}544!llvm.module.flags = !{!0}545 546!0 = !{i32 2, !"Debug Info Version", i32 3}547; CHECK: ![[SP1]] = distinct !DISubprogram(name: "my_async_function",548; CHECK-SAME:                              linkageName: "my_async_function",549; CHECK-SAME:                              scopeLine: 1550!1 = distinct !DISubprogram(name: "my_async_function",551                            linkageName: "my_async_function",552                            scope: !2, file: !3, line: 1, type: !4,553                            scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2)554; CHECK: ![[SP2]] = distinct !DISubprogram(name: "my_async_function",555; CHECK-SAME:                              linkageName: "my_async_functionTQ0_",556; CHECK-SAME:                              scopeLine: 2557!2 = distinct !DICompileUnit(language: DW_LANG_Swift, file: !3, emissionKind: FullDebug)558!3 = !DIFile(filename: "/tmp/1.swift", directory: "/")559!4 = !DISubroutineType(types: !{})560!5 = !DILocation(line: 2, column: 0, scope: !1)561 562; CHECK: ![[SP3]] = distinct !DISubprogram(name: "my_async_function2",563; CHECK-SAME:                              linkageName: "my_async_function2",564; CHECK-SAME:                              scopeLine: 1565!6 = distinct !DISubprogram(name: "my_async_function2",566                            linkageName: "my_async_function2",567                            scope: !2, file: !3, line: 1, type: !4,568                            scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2)569; CHECK: ![[SP4]] = distinct !DISubprogram(name: "my_async_function2",570; CHECK-SAME:                              linkageName: "my_async_function2.resume.0",571; CHECK-SAME:                              scopeLine: 1572!7 = !DILexicalBlockFile(scope: !6, file: !8, discriminator: 0)573!8 = !DIFile(filename: "/tmp/fake.cpp", directory: "/")574!9 = !DILocation(line: 2, column: 0, scope: !7)575