@@ -111,6 +111,9 @@ co_invoke_fn co_invoke;
111111// CIR-DAG: ![[VoidPromisse:.*]] = !cir.record<struct "folly::coro::Task<void>::promise_type" padded {!u8i}>
112112// CIR-DAG: ![[IntPromisse:.*]] = !cir.record<struct "folly::coro::Task<int>::promise_type" padded {!u8i}>
113113// CIR-DAG: ![[StdString:.*]] = !cir.record<struct "std::string" padded {!u8i}>
114+ // CIR-DAG: ![[CoroHandleVoid:.*]] = !cir.record<struct "std::coroutine_handle<void>" padded {!u8i}>
115+ // CIR-DAG: ![[CoroHandlePromiseVoid:rec_.*]] = !cir.record<struct "std::coroutine_handle<folly::coro::Task<void>::promise_type>" padded {!u8i}>
116+ // CIR-DAG: ![[CoroHandlePromiseInt:rec_.*]] = !cir.record<struct "std::coroutine_handle<folly::coro::Task<int>::promise_type>" padded {!u8i}>
114117// CIR-DAG: ![[SuspendAlways:.*]] = !cir.record<struct "std::suspend_always" padded {!u8i}>
115118
116119// CIR: module {{.*}} {
@@ -160,6 +163,8 @@ VoidTask silly_task() {
160163
161164// CIR: cir.scope {
162165// CIR: %[[SuspendAlwaysAddr:.*]] = cir.alloca ![[SuspendAlways]], {{.*}} ["ref.tmp0"] {alignment = 1 : i64}
166+ // CIR: %[[CoroHandleVoidAddr:.*]] = cir.alloca ![[CoroHandleVoid]], {{.*}} ["agg.tmp0"] {alignment = 1 : i64}
167+ // CIR: %[[CoroHandlePromiseAddr:.*]] = cir.alloca ![[CoroHandlePromiseVoid]], {{.*}} ["agg.tmp1"] {alignment = 1 : i64}
163168
164169// Effectively execute `coawait promise_type::initial_suspend()` by calling initial_suspend() and getting
165170// the suspend_always struct to use for cir.await. Note that we return by-value since we defer ABI lowering
@@ -175,8 +180,28 @@ VoidTask silly_task() {
175180// First regions `ready` has a special cir.yield code to veto suspension.
176181
177182// CIR: cir.await(init, ready : {
178- // CIR: cir.condition({{.*}})
183+ // CIR: %[[ReadyVeto:.*]] = cir.scope {
184+ // CIR: %[[TmpCallRes:.*]] = cir.call @_ZNSt14suspend_always11await_readyEv(%[[SuspendAlwaysAddr]])
185+ // CIR: cir.yield %[[TmpCallRes:.*]] : !cir.bool
186+ // CIR: }
187+ // CIR: cir.condition(%[[ReadyVeto]])
188+
189+ // Second region `suspend` contains the actual suspend logic.
190+ //
191+ // - Start by getting the coroutine handle using from_address().
192+ // - Implicit convert coroutine handle from task specific promisse
193+ // specialization to a void one.
194+ // - Call suspend_always::await_suspend() passing the handle.
195+ //
196+ // FIXME: add veto support for non-void await_suspends.
197+
179198// CIR: }, suspend : {
199+ // CIR: %[[FromAddrRes:.*]] = cir.call @_ZNSt16coroutine_handleIN5folly4coro4TaskIvE12promise_typeEE12from_addressEPv(%[[CoroFrameAddr]])
200+ // CIR: cir.store{{.*}} %[[FromAddrRes]], %[[CoroHandlePromiseAddr]] : ![[CoroHandlePromiseVoid]]
201+ // CIR: %[[CoroHandlePromiseReload:.*]] = cir.load{{.*}} %[[CoroHandlePromiseAddr]]
202+ // CIR: cir.call @_ZNSt16coroutine_handleIvEC1IN5folly4coro4TaskIvE12promise_typeEEES_IT_E(%[[CoroHandleVoidAddr]], %[[CoroHandlePromiseReload]])
203+ // CIR: %[[CoroHandleVoidReload:.*]] = cir.load{{.*}} %[[CoroHandleVoidAddr]] : !cir.ptr<![[CoroHandleVoid]]>, ![[CoroHandleVoid]]
204+ // CIR: cir.call @_ZNSt14suspend_always13await_suspendESt16coroutine_handleIvE(%[[SuspendAlwaysAddr]], %[[CoroHandleVoidReload]])
180205// CIR: cir.yield
181206// CIR: }, resume : {
182207// CIR: cir.yield
@@ -203,11 +228,23 @@ folly::coro::Task<int> byRef(const std::string& s) {
203228// CIR: cir.store {{.*}} %[[RetObj]], %[[IntTaskAddr]] : ![[IntTask]]
204229// CIR: cir.scope {
205230// CIR: %[[SuspendAlwaysAddr:.*]] = cir.alloca ![[SuspendAlways]], {{.*}} ["ref.tmp0"] {alignment = 1 : i64}
231+ // CIR: %[[CoroHandleVoidAddr:.*]] = cir.alloca ![[CoroHandleVoid]], {{.*}} ["agg.tmp0"] {alignment = 1 : i64}
232+ // CIR: %[[CoroHandlePromiseAddr:.*]] = cir.alloca ![[CoroHandlePromiseInt]], {{.*}} ["agg.tmp1"] {alignment = 1 : i64}
206233// CIR: %[[Tmp0:.*]] = cir.call @_ZN5folly4coro4TaskIiE12promise_type15initial_suspendEv(%[[IntPromisseAddr]])
207234// CIR: cir.await(init, ready : {
208- // CIR: cir.condition({{.*}})
235+ // CIR: %[[ReadyVeto:.*]] = cir.scope {
236+ // CIR: %[[TmpCallRes:.*]] = cir.call @_ZNSt14suspend_always11await_readyEv(%[[SuspendAlwaysAddr]])
237+ // CIR: cir.yield %[[TmpCallRes:.*]] : !cir.bool
238+ // CIR: }
239+ // CIR: cir.condition(%[[ReadyVeto]])
209240// CIR: }, suspend : {
210- // CIR: cir.yield
241+ // CIR: %[[FromAddrRes:.*]] = cir.call @_ZNSt16coroutine_handleIN5folly4coro4TaskIiE12promise_typeEE12from_addressEPv(%[[CoroFrameAddr:.*]])
242+ // CIR: cir.store{{.*}} %[[FromAddrRes]], %[[CoroHandlePromiseAddr]] : ![[CoroHandlePromiseInt]]
243+ // CIR: %[[CoroHandlePromiseReload:.*]] = cir.load{{.*}} %[[CoroHandlePromiseAddr]]
244+ // CIR: cir.call @_ZNSt16coroutine_handleIvEC1IN5folly4coro4TaskIiE12promise_typeEEES_IT_E(%[[CoroHandleVoidAddr]], %[[CoroHandlePromiseReload]])
245+ // CIR: %[[CoroHandleVoidReload:.*]] = cir.load{{.*}} %[[CoroHandleVoidAddr]] : !cir.ptr<![[CoroHandleVoid]]>, ![[CoroHandleVoid]]
246+ // CIR: cir.call @_ZNSt14suspend_always13await_suspendESt16coroutine_handleIvE(%[[SuspendAlwaysAddr]], %[[CoroHandleVoidReload]])
247+ // CIR: cir.yield
211248// CIR: }, resume : {
212249// CIR: cir.yield
213250// CIR: },)
0 commit comments