1a6628e59SEugene Zhulenev// RUN: mlir-opt %s -async-runtime-ref-counting | FileCheck %s 2a6628e59SEugene Zhulenev 3a6628e59SEugene Zhulenev// CHECK-LABEL: @token 4*5e7dea22SRiver Riddlefunc.func private @token() -> !async.token 5a6628e59SEugene Zhulenev 6a6628e59SEugene Zhulenev// CHECK-LABEL: @cond 7*5e7dea22SRiver Riddlefunc.func private @cond() -> i1 8a6628e59SEugene Zhulenev 9a6628e59SEugene Zhulenev// CHECK-LABEL: @take_token 10*5e7dea22SRiver Riddlefunc.func private @take_token(%arg0: !async.token) 11a6628e59SEugene Zhulenev 12a6628e59SEugene Zhulenev// CHECK-LABEL: @token_arg_no_uses 13a6628e59SEugene Zhulenev// CHECK: %[[TOKEN:.*]]: !async.token 14*5e7dea22SRiver Riddlefunc.func @token_arg_no_uses(%arg0: !async.token) { 1592db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 16a6628e59SEugene Zhulenev return 17a6628e59SEugene Zhulenev} 18a6628e59SEugene Zhulenev 19a6628e59SEugene Zhulenev// CHECK-LABEL: @token_value_no_uses 20*5e7dea22SRiver Riddlefunc.func @token_value_no_uses() { 21a6628e59SEugene Zhulenev // CHECK: %[[TOKEN:.*]] = async.runtime.create : !async.token 2292db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 23a6628e59SEugene Zhulenev %0 = async.runtime.create : !async.token 24a6628e59SEugene Zhulenev return 25a6628e59SEugene Zhulenev} 26a6628e59SEugene Zhulenev 27a6628e59SEugene Zhulenev// CHECK-LABEL: @token_returned_no_uses 28*5e7dea22SRiver Riddlefunc.func @token_returned_no_uses() { 29a6628e59SEugene Zhulenev // CHECK: %[[TOKEN:.*]] = call @token 3092db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 31a6628e59SEugene Zhulenev %0 = call @token() : () -> !async.token 32a6628e59SEugene Zhulenev return 33a6628e59SEugene Zhulenev} 34a6628e59SEugene Zhulenev 35a6628e59SEugene Zhulenev// CHECK-LABEL: @token_arg_to_func 36a6628e59SEugene Zhulenev// CHECK: %[[TOKEN:.*]]: !async.token 37*5e7dea22SRiver Riddlefunc.func @token_arg_to_func(%arg0: !async.token) { 3892db09cdSEugene Zhulenev // CHECK: async.runtime.add_ref %[[TOKEN]] {count = 1 : i64} : !async.token 39a6628e59SEugene Zhulenev call @take_token(%arg0): (!async.token) -> () 4092db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} : !async.token 41a6628e59SEugene Zhulenev return 42a6628e59SEugene Zhulenev} 43a6628e59SEugene Zhulenev 44a6628e59SEugene Zhulenev// CHECK-LABEL: @token_value_to_func 45*5e7dea22SRiver Riddlefunc.func @token_value_to_func() { 46a6628e59SEugene Zhulenev // CHECK: %[[TOKEN:.*]] = async.runtime.create : !async.token 47a6628e59SEugene Zhulenev %0 = async.runtime.create : !async.token 4892db09cdSEugene Zhulenev // CHECK: async.runtime.add_ref %[[TOKEN]] {count = 1 : i64} : !async.token 49a6628e59SEugene Zhulenev call @take_token(%0): (!async.token) -> () 5092db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 51a6628e59SEugene Zhulenev return 52a6628e59SEugene Zhulenev} 53a6628e59SEugene Zhulenev 54a6628e59SEugene Zhulenev// CHECK-LABEL: @token_arg_cond_br_await_with_fallthough 55a6628e59SEugene Zhulenev// CHECK: %[[TOKEN:.*]]: !async.token 56*5e7dea22SRiver Riddlefunc.func @token_arg_cond_br_await_with_fallthough(%arg0: !async.token, %arg1: i1) { 57ace01605SRiver Riddle // CHECK: cf.cond_br 58a6628e59SEugene Zhulenev // CHECK-SAME: ^[[BB1:.*]], ^[[BB2:.*]] 59ace01605SRiver Riddle cf.cond_br %arg1, ^bb1, ^bb2 60a6628e59SEugene Zhulenev^bb1: 61a6628e59SEugene Zhulenev // CHECK: ^[[BB1]]: 62ace01605SRiver Riddle // CHECK: cf.br ^[[BB2]] 63ace01605SRiver Riddle cf.br ^bb2 64a6628e59SEugene Zhulenev^bb2: 65a6628e59SEugene Zhulenev // CHECK: ^[[BB2]]: 66a6628e59SEugene Zhulenev // CHECK: async.runtime.await %[[TOKEN]] 6792db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 68a6628e59SEugene Zhulenev async.runtime.await %arg0 : !async.token 69a6628e59SEugene Zhulenev return 70a6628e59SEugene Zhulenev} 71a6628e59SEugene Zhulenev 72a6628e59SEugene Zhulenev// CHECK-LABEL: @token_simple_return 73*5e7dea22SRiver Riddlefunc.func @token_simple_return() -> !async.token { 74a6628e59SEugene Zhulenev // CHECK: %[[TOKEN:.*]] = async.runtime.create : !async.token 75a6628e59SEugene Zhulenev %token = async.runtime.create : !async.token 76a6628e59SEugene Zhulenev // CHECK: return %[[TOKEN]] 77a6628e59SEugene Zhulenev return %token : !async.token 78a6628e59SEugene Zhulenev} 79a6628e59SEugene Zhulenev 80a6628e59SEugene Zhulenev// CHECK-LABEL: @token_coro_return 81a6628e59SEugene Zhulenev// CHECK-NOT: async.runtime.drop_ref 82a6628e59SEugene Zhulenev// CHECK-NOT: async.runtime.add_ref 83*5e7dea22SRiver Riddlefunc.func @token_coro_return() -> !async.token { 84a6628e59SEugene Zhulenev %token = async.runtime.create : !async.token 85a6628e59SEugene Zhulenev %id = async.coro.id 86a6628e59SEugene Zhulenev %hdl = async.coro.begin %id 87a6628e59SEugene Zhulenev %saved = async.coro.save %hdl 88a6628e59SEugene Zhulenev async.runtime.resume %hdl 89a6628e59SEugene Zhulenev async.coro.suspend %saved, ^suspend, ^resume, ^cleanup 90a6628e59SEugene Zhulenev^resume: 91ace01605SRiver Riddle cf.br ^cleanup 92a6628e59SEugene Zhulenev^cleanup: 93a6628e59SEugene Zhulenev async.coro.free %id, %hdl 94ace01605SRiver Riddle cf.br ^suspend 95a6628e59SEugene Zhulenev^suspend: 96a6628e59SEugene Zhulenev async.coro.end %hdl 97a6628e59SEugene Zhulenev return %token : !async.token 98a6628e59SEugene Zhulenev} 99a6628e59SEugene Zhulenev 100a6628e59SEugene Zhulenev// CHECK-LABEL: @token_coro_await_and_resume 101a6628e59SEugene Zhulenev// CHECK: %[[TOKEN:.*]]: !async.token 102*5e7dea22SRiver Riddlefunc.func @token_coro_await_and_resume(%arg0: !async.token) -> !async.token { 103a6628e59SEugene Zhulenev %token = async.runtime.create : !async.token 104a6628e59SEugene Zhulenev %id = async.coro.id 105a6628e59SEugene Zhulenev %hdl = async.coro.begin %id 106a6628e59SEugene Zhulenev %saved = async.coro.save %hdl 107a6628e59SEugene Zhulenev // CHECK: async.runtime.await_and_resume %[[TOKEN]] 108a6628e59SEugene Zhulenev async.runtime.await_and_resume %arg0, %hdl : !async.token 10992db09cdSEugene Zhulenev // CHECK-NEXT: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 110a6628e59SEugene Zhulenev async.coro.suspend %saved, ^suspend, ^resume, ^cleanup 111a6628e59SEugene Zhulenev^resume: 112ace01605SRiver Riddle cf.br ^cleanup 113a6628e59SEugene Zhulenev^cleanup: 114a6628e59SEugene Zhulenev async.coro.free %id, %hdl 115ace01605SRiver Riddle cf.br ^suspend 116a6628e59SEugene Zhulenev^suspend: 117a6628e59SEugene Zhulenev async.coro.end %hdl 118a6628e59SEugene Zhulenev return %token : !async.token 119a6628e59SEugene Zhulenev} 120a6628e59SEugene Zhulenev 121a6628e59SEugene Zhulenev// CHECK-LABEL: @value_coro_await_and_resume 122a6628e59SEugene Zhulenev// CHECK: %[[VALUE:.*]]: !async.value<f32> 123*5e7dea22SRiver Riddlefunc.func @value_coro_await_and_resume(%arg0: !async.value<f32>) -> !async.token { 124a6628e59SEugene Zhulenev %token = async.runtime.create : !async.token 125a6628e59SEugene Zhulenev %id = async.coro.id 126a6628e59SEugene Zhulenev %hdl = async.coro.begin %id 127a6628e59SEugene Zhulenev %saved = async.coro.save %hdl 128a6628e59SEugene Zhulenev // CHECK: async.runtime.await_and_resume %[[VALUE]] 129a6628e59SEugene Zhulenev async.runtime.await_and_resume %arg0, %hdl : !async.value<f32> 130a6628e59SEugene Zhulenev // CHECK: async.coro.suspend 131a6628e59SEugene Zhulenev // CHECK-SAME: ^[[SUSPEND:.*]], ^[[RESUME:.*]], ^[[CLEANUP:.*]] 132a6628e59SEugene Zhulenev async.coro.suspend %saved, ^suspend, ^resume, ^cleanup 133a6628e59SEugene Zhulenev^resume: 134a6628e59SEugene Zhulenev // CHECK: ^[[RESUME]]: 135a6628e59SEugene Zhulenev // CHECK: %[[LOADED:.*]] = async.runtime.load %[[VALUE]] 13692db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[VALUE]] {count = 1 : i64} 137a6628e59SEugene Zhulenev %0 = async.runtime.load %arg0 : !async.value<f32> 138a54f4eaeSMogball // CHECK: arith.addf %[[LOADED]], %[[LOADED]] 139a54f4eaeSMogball %1 = arith.addf %0, %0 : f32 140ace01605SRiver Riddle cf.br ^cleanup 141a6628e59SEugene Zhulenev^cleanup: 142a6628e59SEugene Zhulenev async.coro.free %id, %hdl 143ace01605SRiver Riddle cf.br ^suspend 144a6628e59SEugene Zhulenev^suspend: 145a6628e59SEugene Zhulenev async.coro.end %hdl 146a6628e59SEugene Zhulenev return %token : !async.token 147a6628e59SEugene Zhulenev} 148a6628e59SEugene Zhulenev 149a6628e59SEugene Zhulenev// CHECK-LABEL: @outlined_async_execute 150a6628e59SEugene Zhulenev// CHECK: %[[TOKEN:.*]]: !async.token 151*5e7dea22SRiver Riddlefunc.func private @outlined_async_execute(%arg0: !async.token) -> !async.token { 152a6628e59SEugene Zhulenev %0 = async.runtime.create : !async.token 153a6628e59SEugene Zhulenev %1 = async.coro.id 154a6628e59SEugene Zhulenev %2 = async.coro.begin %1 155a6628e59SEugene Zhulenev %3 = async.coro.save %2 156a6628e59SEugene Zhulenev async.runtime.resume %2 157a6628e59SEugene Zhulenev // CHECK: async.coro.suspend 158a6628e59SEugene Zhulenev async.coro.suspend %3, ^suspend, ^resume, ^cleanup 159a6628e59SEugene Zhulenev^resume: 160a6628e59SEugene Zhulenev // CHECK: ^[[RESUME:.*]]: 161a6628e59SEugene Zhulenev %4 = async.coro.save %2 162a6628e59SEugene Zhulenev async.runtime.await_and_resume %arg0, %2 : !async.token 16392db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 164a6628e59SEugene Zhulenev // CHECK: async.coro.suspend 165a6628e59SEugene Zhulenev async.coro.suspend %4, ^suspend, ^resume_1, ^cleanup 166a6628e59SEugene Zhulenev^resume_1: 167a6628e59SEugene Zhulenev // CHECK: ^[[RESUME_1:.*]]: 168a6628e59SEugene Zhulenev // CHECK: async.runtime.set_available 169a6628e59SEugene Zhulenev async.runtime.set_available %0 : !async.token 170ace01605SRiver Riddle cf.br ^cleanup 171a6628e59SEugene Zhulenev^cleanup: 172a6628e59SEugene Zhulenev // CHECK: ^[[CLEANUP:.*]]: 173a6628e59SEugene Zhulenev // CHECK: async.coro.free 174a6628e59SEugene Zhulenev async.coro.free %1, %2 175ace01605SRiver Riddle cf.br ^suspend 176a6628e59SEugene Zhulenev^suspend: 177a6628e59SEugene Zhulenev // CHECK: ^[[SUSPEND:.*]]: 178a6628e59SEugene Zhulenev // CHECK: async.coro.end 179a6628e59SEugene Zhulenev async.coro.end %2 180a6628e59SEugene Zhulenev return %0 : !async.token 181a6628e59SEugene Zhulenev} 182a6628e59SEugene Zhulenev 183a6628e59SEugene Zhulenev// CHECK-LABEL: @token_await_inside_nested_region 184a6628e59SEugene Zhulenev// CHECK: %[[ARG:.*]]: i1 185*5e7dea22SRiver Riddlefunc.func @token_await_inside_nested_region(%arg0: i1) { 186a6628e59SEugene Zhulenev // CHECK: %[[TOKEN:.*]] = call @token() 187a6628e59SEugene Zhulenev %token = call @token() : () -> !async.token 188a6628e59SEugene Zhulenev // CHECK: scf.if %[[ARG]] { 189a6628e59SEugene Zhulenev scf.if %arg0 { 190a6628e59SEugene Zhulenev // CHECK: async.runtime.await %[[TOKEN]] 191a6628e59SEugene Zhulenev async.runtime.await %token : !async.token 192a6628e59SEugene Zhulenev } 193a6628e59SEugene Zhulenev // CHECK: } 19492db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 195a6628e59SEugene Zhulenev // CHECK: return 196a6628e59SEugene Zhulenev return 197a6628e59SEugene Zhulenev} 198a6628e59SEugene Zhulenev 199a6628e59SEugene Zhulenev// CHECK-LABEL: @token_defined_in_the_loop 200*5e7dea22SRiver Riddlefunc.func @token_defined_in_the_loop() { 201ace01605SRiver Riddle cf.br ^bb1 202a6628e59SEugene Zhulenev^bb1: 203a6628e59SEugene Zhulenev // CHECK: ^[[BB1:.*]]: 204a6628e59SEugene Zhulenev // CHECK: %[[TOKEN:.*]] = call @token() 205a6628e59SEugene Zhulenev %token = call @token() : () -> !async.token 206a6628e59SEugene Zhulenev // CHECK: async.runtime.await %[[TOKEN]] 20792db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 208a6628e59SEugene Zhulenev async.runtime.await %token : !async.token 209a6628e59SEugene Zhulenev %0 = call @cond(): () -> (i1) 210ace01605SRiver Riddle cf.cond_br %0, ^bb1, ^bb2 211a6628e59SEugene Zhulenev^bb2: 212a6628e59SEugene Zhulenev // CHECK: ^[[BB2:.*]]: 213a6628e59SEugene Zhulenev // CHECK: return 214a6628e59SEugene Zhulenev return 215a6628e59SEugene Zhulenev} 216c412979cSEugene Zhulenev 217c412979cSEugene Zhulenev// CHECK-LABEL: @divergent_liveness_one_token 218*5e7dea22SRiver Riddlefunc.func @divergent_liveness_one_token(%arg0 : i1) { 219c412979cSEugene Zhulenev // CHECK: %[[TOKEN:.*]] = call @token() 220c412979cSEugene Zhulenev %token = call @token() : () -> !async.token 221ace01605SRiver Riddle // CHECK: cf.cond_br %arg0, ^[[LIVE_IN:.*]], ^[[REF_COUNTING:.*]] 222ace01605SRiver Riddle cf.cond_br %arg0, ^bb1, ^bb2 223c412979cSEugene Zhulenev^bb1: 224c412979cSEugene Zhulenev // CHECK: ^[[LIVE_IN]]: 225c412979cSEugene Zhulenev // CHECK: async.runtime.await %[[TOKEN]] 22692db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 227ace01605SRiver Riddle // CHECK: cf.br ^[[RETURN:.*]] 228c412979cSEugene Zhulenev async.runtime.await %token : !async.token 229ace01605SRiver Riddle cf.br ^bb2 230c412979cSEugene Zhulenev // CHECK: ^[[REF_COUNTING:.*]]: 23192db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 232ace01605SRiver Riddle // CHECK: cf.br ^[[RETURN:.*]] 233c412979cSEugene Zhulenev^bb2: 234c412979cSEugene Zhulenev // CHECK: ^[[RETURN]]: 235c412979cSEugene Zhulenev // CHECK: return 236c412979cSEugene Zhulenev return 237c412979cSEugene Zhulenev} 238c412979cSEugene Zhulenev 239c412979cSEugene Zhulenev// CHECK-LABEL: @divergent_liveness_unique_predecessor 240*5e7dea22SRiver Riddlefunc.func @divergent_liveness_unique_predecessor(%arg0 : i1) { 241c412979cSEugene Zhulenev // CHECK: %[[TOKEN:.*]] = call @token() 242c412979cSEugene Zhulenev %token = call @token() : () -> !async.token 243ace01605SRiver Riddle // CHECK: cf.cond_br %arg0, ^[[LIVE_IN:.*]], ^[[NO_LIVE_IN:.*]] 244ace01605SRiver Riddle cf.cond_br %arg0, ^bb2, ^bb1 245c412979cSEugene Zhulenev^bb1: 246c412979cSEugene Zhulenev // CHECK: ^[[NO_LIVE_IN]]: 24792db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 248ace01605SRiver Riddle // CHECK: cf.br ^[[RETURN:.*]] 249ace01605SRiver Riddle cf.br ^bb3 250c412979cSEugene Zhulenev^bb2: 251c412979cSEugene Zhulenev // CHECK: ^[[LIVE_IN]]: 252c412979cSEugene Zhulenev // CHECK: async.runtime.await %[[TOKEN]] 25392db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} 254ace01605SRiver Riddle // CHECK: cf.br ^[[RETURN]] 255c412979cSEugene Zhulenev async.runtime.await %token : !async.token 256ace01605SRiver Riddle cf.br ^bb3 257c412979cSEugene Zhulenev^bb3: 258c412979cSEugene Zhulenev // CHECK: ^[[RETURN]]: 259c412979cSEugene Zhulenev // CHECK: return 260c412979cSEugene Zhulenev return 261c412979cSEugene Zhulenev} 262c412979cSEugene Zhulenev 263c412979cSEugene Zhulenev// CHECK-LABEL: @divergent_liveness_two_tokens 264*5e7dea22SRiver Riddlefunc.func @divergent_liveness_two_tokens(%arg0 : i1) { 265c412979cSEugene Zhulenev // CHECK: %[[TOKEN0:.*]] = call @token() 266c412979cSEugene Zhulenev // CHECK: %[[TOKEN1:.*]] = call @token() 267c412979cSEugene Zhulenev %token0 = call @token() : () -> !async.token 268c412979cSEugene Zhulenev %token1 = call @token() : () -> !async.token 269ace01605SRiver Riddle // CHECK: cf.cond_br %arg0, ^[[AWAIT0:.*]], ^[[AWAIT1:.*]] 270ace01605SRiver Riddle cf.cond_br %arg0, ^await0, ^await1 271c412979cSEugene Zhulenev^await0: 272c412979cSEugene Zhulenev // CHECK: ^[[AWAIT0]]: 27392db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN1]] {count = 1 : i64} 274c412979cSEugene Zhulenev // CHECK: async.runtime.await %[[TOKEN0]] 27592db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN0]] {count = 1 : i64} 276ace01605SRiver Riddle // CHECK: cf.br ^[[RETURN:.*]] 277c412979cSEugene Zhulenev async.runtime.await %token0 : !async.token 278ace01605SRiver Riddle cf.br ^ret 279c412979cSEugene Zhulenev^await1: 280c412979cSEugene Zhulenev // CHECK: ^[[AWAIT1]]: 28192db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN0]] {count = 1 : i64} 282c412979cSEugene Zhulenev // CHECK: async.runtime.await %[[TOKEN1]] 28392db09cdSEugene Zhulenev // CHECK: async.runtime.drop_ref %[[TOKEN1]] {count = 1 : i64} 284ace01605SRiver Riddle // CHECK: cf.br ^[[RETURN]] 285c412979cSEugene Zhulenev async.runtime.await %token1 : !async.token 286ace01605SRiver Riddle cf.br ^ret 287c412979cSEugene Zhulenev^ret: 288c412979cSEugene Zhulenev // CHECK: ^[[RETURN]]: 289c412979cSEugene Zhulenev // CHECK: return 290c412979cSEugene Zhulenev return 291c412979cSEugene Zhulenev} 292