[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / Coroutines / coro-async-unreachable.ll
blob4670eea92b57b77b6bc1b30c1012b837e6720fb0
1 ; RUN: opt < %s -enable-coroutines -passes='default<O2>' -S | FileCheck --check-prefixes=CHECK %s
3 target datalayout = "p:64:64:64"
5 %async.task = type { i64 }
6 %async.actor = type { i64 }
7 %async.fp = type <{ i32, i32 }>
9 %async.ctxt = type { i8*, void (i8*, %async.task*, %async.actor*)* }
11 ; The async callee.
12 @my_other_async_function_fp = external global <{ i32, i32 }>
13 declare void @my_other_async_function(i8* %async.ctxt)
15 ; Function that implements the dispatch to the callee function.
16 define swiftcc void @my_async_function.my_other_async_function_fp.apply(i8* %fnPtr, i8* %async.ctxt, %async.task* %task, %async.actor* %actor) {
17   %callee = bitcast i8* %fnPtr to void(i8*, %async.task*, %async.actor*)*
18   tail call swiftcc void %callee(i8* %async.ctxt, %async.task* %task, %async.actor* %actor)
19   ret void
22 declare void @some_user(i64)
23 declare void @some_may_write(i64*)
25 define i8* @resume_context_projection(i8* %ctxt) {
26 entry:
27   %resume_ctxt_addr = bitcast i8* %ctxt to i8**
28   %resume_ctxt = load i8*, i8** %resume_ctxt_addr, align 8
29   ret i8* %resume_ctxt
33 @unreachable_fp = constant <{ i32, i32 }>
34   <{ i32 trunc ( ; Relative pointer to async function
35        i64 sub (
36          i64 ptrtoint (void (i8*, %async.task*, %async.actor*)* @unreachable to i64),
37          i64 ptrtoint (i32* getelementptr inbounds (<{ i32, i32 }>, <{ i32, i32 }>* @unreachable_fp, i32 0, i32 1) to i64)
38        )
39      to i32),
40      i32 128    ; Initial async context size without space for frame
43 define swiftcc void @unreachable(i8* %async.ctxt, %async.task* %task, %async.actor* %actor)  {
44 entry:
45   %tmp = alloca { i64, i64 }, align 8
46   %proj.1 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 0
47   %proj.2 = getelementptr inbounds { i64, i64 }, { i64, i64 }* %tmp, i64 0, i32 1
49   %id = call token @llvm.coro.id.async(i32 128, i32 16, i32 0,
50           i8* bitcast (<{i32, i32}>* @unreachable_fp to i8*))
51   %hdl = call i8* @llvm.coro.begin(token %id, i8* null)
52   store i64 0, i64* %proj.1, align 8
53   store i64 1, i64* %proj.2, align 8
54   call void @some_may_write(i64* %proj.1)
56         ; Begin lowering: apply %my_other_async_function(%args...)
57   ; setup callee context
58   %arg0 = bitcast %async.task* %task to i8*
59   %arg1 = bitcast <{ i32, i32}>* @my_other_async_function_fp to i8*
60   %callee_context = call i8* @llvm.coro.async.context.alloc(i8* %arg0, i8* %arg1)
61         %callee_context.0 = bitcast i8* %callee_context to %async.ctxt*
62   ; store the return continuation
63   %callee_context.return_to_caller.addr = getelementptr inbounds %async.ctxt, %async.ctxt* %callee_context.0, i32 0, i32 1
64   %return_to_caller.addr = bitcast void(i8*, %async.task*, %async.actor*)** %callee_context.return_to_caller.addr to i8**
65   %resume.func_ptr = call i8* @llvm.coro.async.resume()
66   store i8* %resume.func_ptr, i8** %return_to_caller.addr
68   ; store caller context into callee context
69   %callee_context.caller_context.addr = getelementptr inbounds %async.ctxt, %async.ctxt* %callee_context.0, i32 0, i32 0
70   store i8* %async.ctxt, i8** %callee_context.caller_context.addr
71   %resume_proj_fun = bitcast i8*(i8*)* @resume_context_projection to i8*
72   %callee = bitcast void(i8*, %async.task*, %async.actor*)* @asyncSuspend to i8*
73   %res = call {i8*, i8*, i8*} (i32, i8*, i8*, ...) @llvm.coro.suspend.async(i32 0,
74                                                   i8* %resume.func_ptr,
75                                                   i8* %resume_proj_fun,
76                                                   void (i8*, i8*, %async.task*, %async.actor*)* @my_async_function.my_other_async_function_fp.apply,
77                                                   i8* %callee, i8* %callee_context, %async.task* %task, %async.actor *%actor)
79   call void @llvm.coro.async.context.dealloc(i8* %callee_context)
80   %continuation_task_arg = extractvalue {i8*, i8*, i8*} %res, 1
81   %task.2 =  bitcast i8* %continuation_task_arg to %async.task*
82   %val = load i64, i64* %proj.1
83   call void @some_user(i64 %val)
84   %val.2 = load i64, i64* %proj.2
85   call void @some_user(i64 %val.2)
86   unreachable
89 ; CHECK: define swiftcc void @unreachable
90 ; CHECK-NOT: @llvm.coro.suspend.async
91 ; CHECK: return
93 ; CHECK: define internal swiftcc void @unreachable.resume.0
94 ; CHECK: unreachable
96 declare i8* @llvm.coro.prepare.async(i8*)
97 declare token @llvm.coro.id.async(i32, i32, i32, i8*)
98 declare i8* @llvm.coro.begin(token, i8*)
99 declare {i8*, i8*, i8*} @llvm.coro.suspend.async(i32, i8*, i8*, ...)
100 declare i8* @llvm.coro.async.context.alloc(i8*, i8*)
101 declare void @llvm.coro.async.context.dealloc(i8*)
102 declare swiftcc void @asyncReturn(i8*, %async.task*, %async.actor*)
103 declare swiftcc void @asyncSuspend(i8*, %async.task*, %async.actor*)
104 declare i8* @llvm.coro.async.resume()