@@ -91,3 +91,60 @@ entry:
91
91
%retf = tuple (%ret : $Builtin.Int64, %ret2_1 : $Builtin.Int64, %ret2_2 : $Builtin.Int64)
92
92
return %retf : $(Builtin.Int64, Builtin.Int64, Builtin.Int64)
93
93
}
94
+
95
+ // CHECK-LABEL: coro_ret_indirect
96
+ // CHECK-SAME: ptr{{.*}} [[CTX:%.*]], ptr{{.*}} [[INDIRECT_RET:%.*]], ptr{{.*}} [[ARG:%.*]], ptr{{.*}} [[TYPE:%.*]])
97
+ sil @coro_ret_indirect : $@yield_once @convention(thin) <T> (@in T) -> (@yields @in T, @out T) {
98
+ bb0(%outt : $*T, %t : $*T):
99
+ // CHECK-32: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:4]], ptr [[CTX]], ptr @"$sxxxlIetAirYi_TC{{(.ptrauth)?}}", ptr @malloc, ptr @free)
100
+ // CHECK-64: [[ID:%.*]] = call token @llvm.coro.id.retcon.once(i32 [[BUFFER_SIZE]], i32 [[BUFFER_ALIGN:8]], ptr [[CTX]], ptr @"$sxxxlIetAirYi_TC{{(.ptrauth)?}}", ptr @malloc, ptr @free)
101
+
102
+ // CHECK: [[IS_UNWIND:%.*]] = call i1 (...) @llvm.coro.suspend.retcon.i1(ptr [[ARG]])
103
+ // CHECK: br i1 [[IS_UNWIND]], label %[[UNWIND_BB:.*]], label %[[RESUME_BB:.*]]
104
+
105
+ // CHECK:[[RESUME_BB]]:
106
+ // CHECK: [[VW_PTR:%.*]] = getelementptr inbounds ptr, ptr [[TYPE]], i64 -1
107
+ // CHECK: [[VW:%.*]] = load ptr, ptr [[VW_PTR]]
108
+ // CHECK: [[ASSIGN_PTR:%.*]] = getelementptr inbounds ptr, ptr [[VW]], i32 3
109
+ // CHECK: [[ASSIGN:%.*]] = load ptr, ptr [[ASSIGN_PTR]]
110
+ // CHECK: call ptr [[ASSIGN]](ptr [[INDIRECT_RET]], ptr [[ARG]], ptr [[TYPE]]) #2
111
+
112
+ yield (%t : $*T), resume bb1, unwind bb2
113
+
114
+ bb1:
115
+ copy_addr %t to %outt : $*T
116
+ %r = tuple ()
117
+ return %r : $()
118
+
119
+ bb2:
120
+ unwind
121
+ }
122
+
123
+ // CHECK-LABEL: @test_coro_ret_indirect
124
+ // CHECK-SAME: (i64 [[ARG:%.*]])
125
+ sil [ossa] @test_coro_ret_indirect : $(Builtin.Int64) -> () {
126
+ bb0(%0 : $Builtin.Int64):
127
+ // CHECK: [[ARG_COPY:%.*]] = alloca i64
128
+ // CHECK: [[INDIRECT_RET:%.*]] = alloca i64
129
+ // CHECK: [[FRAME:%.*]] = alloca [32 x i8]
130
+ %coro = function_ref @coro_ret_indirect : $@yield_once @convention(thin) <T> (@in T) -> (@yields @in T, @out T)
131
+ %temp = alloc_stack $Builtin.Int64
132
+ store %0 to [trivial] %temp : $*Builtin.Int64
133
+
134
+ %out = alloc_stack $Builtin.Int64
135
+
136
+ // CHECK: store i64 [[ARG]], ptr [[ARG_COPY]]
137
+ // CHECK: [[CTX:%.*]] = getelementptr inbounds [32 x i8], ptr [[FRAME]], i32 0, i32 0
138
+ // CHECK: [[CORO:%.*]] = call ptr @llvm.coro.prepare.retcon(ptr @coro_ret_indirect)
139
+ // CHECK: [[FRAME:%.*]] = call swiftcc { ptr, ptr } [[CORO]](ptr{{.*}} [[CTX]], ptr [[INDIRECT_RET]], ptr noalias [[ARG_COPY]], ptr getelementptr inbounds (%swift.full_existential_type, ptr @{{.*}}
140
+
141
+ (%f1, %token) = begin_apply %coro<Builtin.Int64>(%out, %temp) : $@yield_once @convention(thin) <T> (@in T) -> (@yields @in T, @out T)
142
+
143
+ %f2 = end_apply %token as $()
144
+
145
+ dealloc_stack %out : $*Builtin.Int64
146
+ dealloc_stack %temp : $*Builtin.Int64
147
+
148
+ %r = tuple ()
149
+ return %r : $()
150
+ }
0 commit comments