| // RUN: %target-swift-frontend -emit-ir -disable-llvm-optzns %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize |
| |
| import Builtin |
| |
| sil @marker : $(Builtin.Int32) -> () |
| |
| // CHECK-LABEL: define{{( protected)?}} swiftcc i8* @test_simple |
| // CHECK-32-SAME: i8* noalias dereferenceable([[BUFFER_SIZE:16]])) |
| // CHECK-64-SAME: (i8* noalias dereferenceable([[BUFFER_SIZE:32]])) |
| sil @test_simple : $@yield_once () -> () { |
| entry: |
| // CHECK-32: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], i8* %0, i8* bitcast (void (i8*, i1)* @"$SIet_TC" to i8*), i8* bitcast (i8* (i32)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) |
| // CHECK-64: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], i8* %0, i8* bitcast (void (i8*, i1)* @"$SIet_TC" to i8*), i8* bitcast (i8* (i64)* @malloc to i8*), i8* bitcast (void (i8*)* @free to i8*)) |
| // CHECK-NEXT: [[BEGIN:%.*]] = call i8* @llvm.coro.begin(token [[ID]], i8* null) |
| |
| // CHECK-NEXT: call swiftcc void @marker(i32 1000) |
| %marker = function_ref @marker : $@convention(thin) (Builtin.Int32) -> () |
| %1000 = integer_literal $Builtin.Int32, 1000 |
| apply %marker(%1000) : $@convention(thin) (Builtin.Int32) -> () |
| |
| // CHECK-NEXT: [[IS_UNWIND:%.*]] = call i1 (...) @llvm.coro.suspend.retcon.i1() |
| // CHECK-NEXT: br i1 [[IS_UNWIND]] |
| yield (), resume resume, unwind unwind |
| |
| resume: |
| // CHECK: call swiftcc void @marker(i32 2000) |
| %2000 = integer_literal $Builtin.Int32, 2000 |
| apply %marker(%2000) : $@convention(thin) (Builtin.Int32) -> () |
| // CHECK: br label %coro.end |
| %ret = tuple () |
| return %ret : $() |
| |
| unwind: |
| // CHECK: call swiftcc void @marker(i32 3000) |
| %3000 = integer_literal $Builtin.Int32, 3000 |
| apply %marker(%3000) : $@convention(thin) (Builtin.Int32) -> () |
| // CHECK: br label %coro.end |
| unwind |
| |
| // CHECK: coro.end: |
| // CHECK: call i1 @llvm.coro.end(i8* [[BEGIN]], i1 false) |
| // CHECK-NEXT: unreachable |
| } |
| |
| // CHECK-LABEL: declare{{( protected)?}} swiftcc void @"$SIet_TC" |
| // CHECK-SAME: (i8* noalias dereferenceable([[BUFFER_SIZE]]), i1) |
| |
| // CHECK-LABEL: define{{( protected)?}} swiftcc void @test_simple_call(i1) |
| sil @test_simple_call : $(Builtin.Int1) -> () { |
| entry(%flag : $Builtin.Int1): |
| // Allocate the buffer. |
| // CHECK: [[T0:%.*]] = alloca {{\[}}[[BUFFER_SIZE]] x i8], align [[BUFFER_ALIGN]] |
| // CHECK-NEXT: [[BUFFER:%.*]] = getelementptr inbounds {{\[}}[[BUFFER_SIZE]] x i8], {{\[}}[[BUFFER_SIZE]] x i8]* [[T0]], i32 0, i32 0 |
| // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) |
| |
| // Prepare the continuation function pointer to block analysis. |
| // CHECK-NEXT: [[T0:%.*]] = call i8* @llvm.coro.prepare.retcon(i8* bitcast (i8* (i8*)* @test_simple to i8*)) |
| // CHECK-NEXT: [[PREPARE:%.*]] = bitcast i8* [[T0]] to i8* (i8*)* |
| // Call the function pointer. |
| // CHECK-NEXT: [[CONTINUATION:%.*]] = call swiftcc i8* [[PREPARE]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]]) |
| %0 = function_ref @test_simple : $@convention(thin) @yield_once () -> () |
| %token = begin_apply %0() : $@convention(thin) @yield_once () -> () |
| |
| // Branch. |
| // CHECK-NEXT: br i1 %0, |
| cond_br %flag, yes, no |
| |
| yes: |
| // CHECK: [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)* |
| // CHECK-NEXT: call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false) |
| // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) |
| end_apply %token |
| |
| // CHECK-NEXT: br label |
| br cont |
| |
| no: |
| // CHECK: [[T0:%.*]] = bitcast i8* [[CONTINUATION]] to void (i8*, i1)* |
| // CHECK-NEXT: call swiftcc void [[T0]](i8* noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 true) |
| // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 [[BUFFER_SIZE]], i8* [[BUFFER]]) |
| abort_apply %token |
| |
| // CHECK-NEXT: br label |
| br cont |
| |
| cont: |
| // CHECK: ret void |
| %ret = tuple () |
| return %ret : $() |
| } |