@@ -196,3 +196,111 @@ exit:
196
196
destroy_value %value : $FakeOptional<X>
197
197
return %retval : $()
198
198
}
199
+
200
+ // Ensure that an adjacent reborrow phi being reborrowed doesn't get counted as
201
+ // a non-lifetime ending use and extend liveness beyond the instruction where
202
+ // the reborrow occurs.
203
+ // CHECK-LABEL: sil [ossa] @reborrow_adjacent_to_consume_doesnt_extend_lifetime : {{.*}} {
204
+ // CHECK: bb1([[REBORROW:%[^,]+]] : @guaranteed $X, [[VALUE:%[^,]+]] :
205
+ // CHECK: {{bb[0-9]+}}:
206
+ // CHECK: end_borrow [[REBORROW]]
207
+ // CHECK: destroy_value [[VALUE]]
208
+ // CHECK-LABEL: } // end sil function 'reborrow_adjacent_to_consume_doesnt_extend_lifetime'
209
+ sil [ossa] @reborrow_adjacent_to_consume_doesnt_extend_lifetime : $@convention(thin) (@owned X) -> () {
210
+ bb0(%0 : @owned $X):
211
+ %1 = begin_borrow %0 : $X
212
+ br bb1(%1 : $X, %0 : $X)
213
+
214
+ bb1(%3 : @guaranteed $X, %4 : @owned $X):
215
+ cond_br undef, bb2, bb10
216
+
217
+ bb2:
218
+ br bb3
219
+
220
+ bb3:
221
+ br bb4(%3 : $X, %4 : $X)
222
+
223
+ bb4(%8 : @guaranteed $X, %9 : @owned $X):
224
+ cond_br undef, bb5, bb8
225
+
226
+ bb5:
227
+ br bb6
228
+
229
+ bb6:
230
+ br bb7
231
+
232
+ bb7:
233
+ %13 = function_ref @getX : $@convention(thin) () -> @owned X
234
+ %14 = apply %13() : $@convention(thin) () -> @owned X
235
+ end_borrow %8 : $X
236
+ destroy_value %9 : $X
237
+ %17 = begin_borrow %14 : $X
238
+ br bb4(%17 : $X, %14 : $X)
239
+
240
+ bb8:
241
+ br bb9
242
+
243
+ bb9:
244
+ br bb1(%8 : $X, %9 : $X)
245
+
246
+ bb10:
247
+ // TODO: Remove the copy once it isn't necessary to trigger canonicalization.
248
+ %bogus = copy_value %4 : $X
249
+ destroy_value %bogus : $X
250
+ %23 = tuple ()
251
+ end_borrow %3 : $X
252
+ destroy_value %4 : $X
253
+ return %23 : $()
254
+ }
255
+
256
+ // CHECK-LABEL: sil [ossa] @nohoist_destroy_over_endborrow_nonadjacent_reborrow : {{.*}} {
257
+ // CHECK: end_borrow {{%[^,]+}}
258
+ // CHECK: destroy_value {{%[^,]+}}
259
+ // CHECK-LABEL: } // end sil function 'nohoist_destroy_over_endborrow_nonadjacent_reborrow'
260
+ sil [ossa] @nohoist_destroy_over_endborrow_nonadjacent_reborrow : $@convention(thin) (@owned X) -> () {
261
+ entry(%value_1 : @owned $X):
262
+ %lifetime_1 = begin_borrow %value_1 : $X
263
+ br consume_and_reborrow(%lifetime_1 : $X, %value_1 : $X)
264
+
265
+ consume_and_reborrow(%lifetime_2 : @guaranteed $X, %value_2 : @owned $X):
266
+ br reborrow_only(%lifetime_2 : $X)
267
+
268
+ reborrow_only(%lifetime_3 : @guaranteed $X):
269
+ br exit
270
+
271
+ exit:
272
+ %bogus = copy_value %value_2 : $X
273
+ destroy_value %bogus : $X
274
+ %retval = tuple ()
275
+ end_borrow %lifetime_3 : $X
276
+ destroy_value %value_2 : $X
277
+ return %retval : $()
278
+ }
279
+
280
+ // CHECK-LABEL: sil [ossa] @nohoist_destroy_over_endborrow_nonadjacent_reborrow_2 : {{.*}} {
281
+ // CHECK: end_borrow {{%[^,]+}}
282
+ // CHECK: destroy_value {{%[^,]+}}
283
+ // CHECK-LABEL: } // end sil function 'nohoist_destroy_over_endborrow_nonadjacent_reborrow_2'
284
+ sil [ossa] @nohoist_destroy_over_endborrow_nonadjacent_reborrow_2 : $@convention(thin) (@owned X) -> () {
285
+ entry(%value_1 : @owned $X):
286
+ %lifetime_1 = begin_borrow %value_1 : $X
287
+ br consume_and_reborrow(%lifetime_1 : $X, %value_1 : $X)
288
+
289
+ consume_and_reborrow(%lifetime_2 : @guaranteed $X, %value_2 : @owned $X):
290
+ br reborrow_only_1(%lifetime_2 : $X)
291
+
292
+ reborrow_only_1(%lifetime_3 : @guaranteed $X):
293
+ br reborrow_only_2(%lifetime_3 : $X)
294
+
295
+ reborrow_only_2(%lifetime_4 : @guaranteed $X):
296
+ br exit
297
+
298
+ exit:
299
+ %bogus = copy_value %value_2 : $X
300
+ destroy_value %bogus : $X
301
+ %retval = tuple ()
302
+ end_borrow %lifetime_4 : $X
303
+ destroy_value %value_2 : $X
304
+ return %retval : $()
305
+ }
306
+
0 commit comments