@@ -60,7 +60,12 @@ enum Mixed<T> {
60
60
case i(Int)
61
61
case t(T)
62
62
case o(AnyObject)
63
- };
63
+ }
64
+
65
+ indirect enum RE<T> {
66
+ case recursive(RE, T)
67
+ case other(AnyObject)
68
+ }
64
69
65
70
class TestGeneric<T> {
66
71
init()
@@ -756,9 +761,9 @@ bb0(%0 : @owned $SRef<T>):
756
761
// CHECK: [[L:%.*]] = load_borrow [[E0]] : $*AnyObject
757
762
// CHECK: apply %{{.*}}([[L]]) : $@convention(thin) (@guaranteed AnyObject) -> ()
758
763
// CHECK: [[C:%.*]] = copy_value [[L]] : $AnyObject
759
- // CHECK: end_borrow [[L]] : $AnyObject
760
764
// CHECK: [[E1:%.*]] = struct_element_addr %2 : $*SRef<T>, #SRef.element
761
765
// CHECK: copy_addr [[E1]] to [init] %1 : $*T
766
+ // CHECK: end_borrow [[L]] : $AnyObject
762
767
// CHECK: destroy_addr %2 : $*SRef<T>
763
768
// CHECK: store [[C]] to [init] %0 : $*AnyObject
764
769
// CHECK-NOT: dealloc_stack
@@ -808,9 +813,9 @@ bb0(%0 : @owned $(AnyObject, T)):
808
813
// CHECK: [[L:%.*]] = load_borrow %3 : $*AnyObject
809
814
// CHECK: apply %{{.*}}([[L]]) : $@convention(thin) (@guaranteed AnyObject) -> ()
810
815
// CHECK: [[C:%.*]] = copy_value [[L]] : $AnyObject
811
- // CHECK: end_borrow [[L]] : $AnyObject
812
816
// CHECK: [[E1:%.*]] = tuple_element_addr %2 : $*(AnyObject, T), 1
813
817
// CHECK: copy_addr [[E1]] to [init] %1 : $*T
818
+ // CHECK: end_borrow [[L]] : $AnyObject
814
819
// CHECK: destroy_addr %2 : $*(AnyObject, T)
815
820
// CHECK: store [[C]] to [init] %0 : $*AnyObject
816
821
// CHECK-NOT: dealloc_stack
@@ -2224,9 +2229,9 @@ exit:
2224
2229
// CHECK: [[INSTANCE:%[^,]+]] = unchecked_take_enum_data_addr
2225
2230
// CHECK: [[KLASS_ADDR:%[^,]+]] = tuple_element_addr [[INSTANCE]] {{.*}}, 0
2226
2231
// CHECK: [[KLASS:%[^,]+]] = load_borrow [[KLASS_ADDR]]
2227
- // CHECK: end_borrow [[KLASS]]
2228
2232
// CHECK: [[ANY_ADDR:%[^,]+]] = tuple_element_addr [[INSTANCE]] {{.*}}, 1
2229
2233
// CHECK: apply undef<Any>([[ANY_ADDR]])
2234
+ // CHECK: end_borrow [[KLASS]]
2230
2235
// CHECK: destroy_addr [[INSTANCE]]
2231
2236
// CHECK-LABEL: } // end sil function 'test_destructure_tuple_1_guaranteed'
2232
2237
sil [ossa] @test_destructure_tuple_1_guaranteed : $@convention(thin) () -> () {
@@ -2249,6 +2254,62 @@ exit:
2249
2254
return %505 : $()
2250
2255
}
2251
2256
2257
+ // Check that the end_borrows created on behalf of the destructure_tuple end
2258
+ // after the use of the load_borrow of the projection of the terminator result
2259
+ // of the switch_enum that is guaranteed by that load_borrow.
2260
+ //
2261
+ // CHECK-LABEL: sil [ossa] @test_destructure_tuple_load_borrow_projected_box : {{.*}} {
2262
+ // CHECK: {{bb[0-9]+}}([[OUTER:%[^,]+]] :
2263
+ // CHECK: switch_enum [[OUTER]] : $RE<T>, case #RE.recursive!enumelt: [[OUTER_RECURSIVE:bb[0-9]+]], case #RE.other!enumelt: [[OUTER_OTHER:bb[0-9]+]]
2264
+ // CHECK: [[OUTER_OTHER]]({{%[^,]+}} :
2265
+ // CHECK: br [[EXIT:bb[0-9]+]]
2266
+ // CHECK: [[OUTER_RECURSIVE]]([[TUPLE_BOX:%[^,]+]] :
2267
+ // CHECK-NEXT: [[TUPLE_ADDR:%[^,]+]] = project_box [[TUPLE_BOX]]
2268
+ // CHECK: [[INNER_ADDR:%[^,]+]] = tuple_element_addr [[TUPLE_ADDR]]
2269
+ // CHECK: [[INNER:%[^,]+]] = load_borrow [[INNER_ADDR]]
2270
+ // CHECK: switch_enum [[INNER]] : $RE<T>, case #RE.recursive!enumelt: [[INNER_RECURSIVE:bb[0-9]+]], case #RE.other!enumelt: [[INNER_OTHER:bb[0-9]+]]
2271
+ // CHECK: [[INNER_OTHER]]([[OTHER_BOX:%[^,]+]] :
2272
+ // CHECK: [[OTHER_ADDR:%[^,]+]] = project_box [[OTHER_BOX]]
2273
+ // CHECK: [[OTHER:%[^,]+]] = load_borrow [[OTHER_ADDR]]
2274
+ // CHECK: [[OTHER_COPY:%[^,]+]] = copy_value [[OTHER]]
2275
+ // CHECK: end_borrow [[OTHER]]
2276
+ // CHECK: end_borrow [[INNER]]
2277
+ // CHECK: destroy_value [[OTHER_COPY]]
2278
+ // CHECK: br [[EXIT]]
2279
+ // CHECK: [[INNER_RECURSIVE]]
2280
+ // CHECK: end_borrow [[INNER]]
2281
+ // CHECK: br [[EXIT]]
2282
+ // CHECK-LABEL: } // end sil function 'test_destructure_tuple_load_borrow_projected_box'
2283
+ sil [ossa] @test_destructure_tuple_load_borrow_projected_box : $@convention(thin) <T> (@guaranteed RE<T>) -> () {
2284
+ entry(%o : @guaranteed $RE<T>):
2285
+ switch_enum %o : $RE<T>, case #RE.recursive!enumelt: outer_recursive, case #RE.other!enumelt: outer_other
2286
+
2287
+ outer_other(%other : @guaranteed $<τ_0_0> { var AnyObject } <T>):
2288
+ br exit
2289
+
2290
+ outer_recursive(%tuple_box : @guaranteed $<Tau> { var (RE<Tau>, Tau) } <T>):
2291
+ %tuple_addr = project_box %tuple_box : $<Tau> { var (RE<Tau>, Tau) } <T>, 0
2292
+ %tuple = load_borrow %tuple_addr : $*(RE<T>, T)
2293
+ (%i, %c) = destructure_tuple %tuple : $(RE<T>, T)
2294
+ switch_enum %i : $RE<T>, case #RE.recursive!enumelt: inner_recursive, case #RE.other!enumelt: inner_other
2295
+
2296
+ inner_recursive(%in_tuple_box : @guaranteed $<Tau> { var (RE<Tau>, Tau) } <T>):
2297
+ end_borrow %tuple : $(RE<T>, T)
2298
+ br exit
2299
+
2300
+ inner_other(%s_box : @guaranteed $<Tau> { var AnyObject } <T>):
2301
+ %s_addr = project_box %s_box : $<Tau> { var AnyObject } <T>, 0
2302
+ %s = load_borrow %s_addr : $*AnyObject
2303
+ %sc = copy_value %s : $AnyObject
2304
+ end_borrow %s : $AnyObject
2305
+ end_borrow %tuple : $(RE<T>, T)
2306
+ destroy_value %sc : $AnyObject
2307
+ br exit
2308
+
2309
+ exit:
2310
+ %retval = tuple ()
2311
+ return %retval : $()
2312
+ }
2252
2313
2253
2314
// CHECK-LABEL: sil hidden [ossa] @test_store_1 : {{.*}} {
2254
2315
// CHECK: [[MAYBE_ADDR:%[^,]+]] = alloc_stack $Optional<Self>
0 commit comments