Files
swift-mirror/test/IRGen/yield_once_indirect.sil
Anthony Latsis b5aec4cc34 [test] Remove pre-rebranch nocapture matches
These were added in https://github.com/swiftlang/swift/pull/81375 (and
several other follow-up PRs because we missed a few places) and
are no longer needed.
2025-10-24 02:07:22 +01:00

139 lines
6.1 KiB
Plaintext

// RUN: %target-swift-frontend -emit-irgen -disable-emit-type-malloc-for-coro-frame %s | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-%target-ptrsize-%target-ptrauth -DINT=i%target-ptrsize
import Builtin
import Swift
sil @marker : $(Builtin.Int32) -> ()
class SomeClass {}
sil_vtable SomeClass {}
class SomeSubclass : SomeClass {}
sil_vtable SomeSubclass {}
// This is designed to be formally indirect.
struct Indirect<T: AnyObject> {
var x: Any
var y: T
}
sil @make_indirect : $<T: SomeClass> () -> (@out Indirect<T>)
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { ptr, ptr } @test_simple
// CHECK-32-SAME: (ptr noalias dereferenceable([[BUFFER_SIZE:16]]) %0, ptr %C)
// CHECK-64-SAME: (ptr noalias dereferenceable([[BUFFER_SIZE:32]]) %0, ptr %C)
sil @test_simple : $@yield_once <C: SomeClass> () -> (@yields @in Indirect<C>) {
entry:
// Allocate space for the return value of make_indirect.
// CHECK: [[TEMP:%.*]] = alloca [[INDIRECT:%T19yield_once_indirect8IndirectV]]
// CHECK-32-SAME: , align 4
// CHECK-64-SAME: , align 8
// Coroutine setup.
// CHECK-32-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr %0, ptr @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC", ptr @malloc, ptr @free)
// CHECK-64-NEXT: [[ID:%.*]] = call token (i32, i32, ptr, ptr, ptr, ptr, ...) @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr %0, ptr @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC", ptr @malloc, ptr @free)
// CHECK-NEXT: [[BEGIN:%.*]] = call ptr @llvm.coro.begin(token [[ID]], ptr null)
// CHECK-NEXT: store ptr
// 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: call void @llvm.lifetime.start.p0(i64 {{.*}}, ptr [[TEMP]])
%temp = alloc_stack $Indirect<C>
// CHECK-NEXT: call swiftcc void @make_indirect(ptr noalias sret({{.*}}) captures(none) [[TEMP]], ptr %C)
%make = function_ref @make_indirect : $@convention(thin) <T: SomeClass> () -> (@out Indirect<T>)
apply %make<C>(%temp) : $@convention(thin) <T: SomeClass> () -> (@out Indirect<T>)
// Suspend.
// CHECK-NEXT: [[IS_UNWIND:%.*]] = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr [[TEMP]])
// CHECK-NEXT: br i1 [[IS_UNWIND]]
yield %temp : $*Indirect<C>, 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-NEXT: call void @llvm.lifetime.end.p0(i64 {{.*}}, ptr [[TEMP]])
dealloc_stack %temp : $*Indirect<C>
// CHECK-NEXT: 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-NEXT: call void @llvm.lifetime.end.p0(i64 {{.*}}, ptr [[TEMP]])
dealloc_stack %temp : $*Indirect<C>
// CHECK-NEXT: br label %coro.end
unwind
// CHECK: coro.end:
// CHECK: call i1 @llvm.coro.end(ptr [[BEGIN]], i1 false, token none)
// CHECK-NEXT: unreachable
}
// CHECK-LABEL: declare{{( dllimport)?}}{{( protected)?}} swiftcc void @"$s19yield_once_indirect8IndirectVyxGAA9SomeClassCRbzlIetAYi_TC"
// CHECK-SAME: (ptr noalias dereferenceable([[BUFFER_SIZE]]), i1)
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @test_simple_call(i1 %0)
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], ptr [[T0]], i32 0, i32 0
// CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]])
// CHECK-NEXT: [[TMP:%.*]] = call swiftcc %swift.metadata_response @"$s19yield_once_indirect12SomeSubclassCMa"([[INT]] 0)
// CHECK-NEXT: [[SUBCLASS:%.*]] = extractvalue %swift.metadata_response [[TMP]], 0
// Prepare the continuation function pointer to block analysis.
// CHECK-NEXT: [[T0:%.*]] = call ptr @llvm.coro.prepare.retcon(ptr @test_simple
// Call the function pointer.
// CHECK-NEXT: [[RAMP_RESULT:%.*]] = call swiftcc [[RAMP_RESULT_T:{ ptr, ptr }]] [[T0]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], ptr [[SUBCLASS]])
// CHECK-NEXT: [[CONTINUATION:%.*]] = extractvalue [[RAMP_RESULT_T]] [[RAMP_RESULT]], 0
// CHECK-NEXT: [[ORIG_VALUE:%.*]] = extractvalue [[RAMP_RESULT_T]] [[RAMP_RESULT]], 1
%0 = function_ref @test_simple : $@convention(thin) @yield_once <T: SomeClass> () -> (@yields @in Indirect<T>)
(%value, %token) = begin_apply %0<SomeSubclass>() : $@convention(thin) @yield_once <T: SomeClass> () -> (@yields @in Indirect<T>)
// CHECK-NEXT: call ptr @"$s19yield_once_indirect8IndirectVyAA12SomeSubclassCGWOh"(ptr [[ORIG_VALUE]])
destroy_addr %value : $*Indirect<SomeSubclass>
// Branch.
// CHECK-NEXT: br i1 %0,
cond_br %flag, yes, no
yes:
// CHECK-64-ptrauth: ptrtoint
// CHECK-64-ptrauth-NEXT: ptrauth.blend
// CHECK: call swiftcc void [[CONTINUATION]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 false)
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]])
end_apply %token as $()
// CHECK-NEXT: br label
br cont
no:
// CHECK-64-ptrauth: ptrtoint
// CHECK-64-ptrauth-NEXT: ptrauth.blend
// CHECK: call swiftcc void [[CONTINUATION]](ptr noalias dereferenceable([[BUFFER_SIZE]]) [[BUFFER]], i1 true)
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 [[BUFFER_SIZE]], ptr [[BUFFER]])
abort_apply %token
// CHECK-NEXT: br label
br cont
cont:
// CHECK: ret void
%ret = tuple ()
return %ret : $()
}