@@ -6,9 +6,14 @@ typealias AnyObject = Builtin.AnyObject
66
77class C {}
88class D : C {}
9+ struct S {
10+ @_hasStorage var guts: SGuts
11+ }
12+ class SGuts {}
913
1014sil @getD : $() -> (@owned D)
1115sil @takeC : $(@owned C) -> ()
16+ sil [ossa] @sink : $@convention(thin) <τ_0_0> (@owned τ_0_0) -> ()
1217
1318struct Unmanaged<Instance> where Instance : AnyObject {
1419 unowned(unsafe) var _value: @sil_unmanaged Instance
@@ -70,10 +75,8 @@ bb0(%instance : @guaranteed $Instance):
7075// CHECK: [[TAKE_C:%[^,]+]] = function_ref @takeC
7176// CHECK: [[C:%[^,]+]] = apply [[GET_C]]()
7277// CHECK: [[OUTER_COPY:%[^,]+]] = copy_value [[C]]
73- // CHECK: [[OUTER_UPCAST:%[^,]+]] = upcast [[OUTER_COPY]]
7478// CHECK: [[B:%[^,]+]] = begin_borrow [[C]]
75- // CHECK: [[DEAD_INNER_COPY:%[^,]+]] = copy_value [[B]]
76- // CHECK: destroy_value [[DEAD_INNER_COPY]]
79+ // CHECK: [[OUTER_UPCAST:%[^,]+]] = upcast [[OUTER_COPY]]
7780// CHECK: [[U:%[^,]+]] = upcast [[B]]
7881// CHECK: [[C1:%[^,]+]] = copy_value [[U]]
7982// CHECK: apply [[TAKE_C]]([[C1]])
@@ -97,3 +100,52 @@ sil [ossa] @dont_rewrite_inner_forwarding_user : $@convention(thin) () -> (@owne
97100 destroy_value %d : $D
98101 return %u2 : $C
99102}
103+
104+ // CHECK-LABEL: begin running test {{.*}} on dont_hoist_inner_destructure: canonicalize-borrow-scope
105+ // CHECK-LABEL: sil [ossa] @dont_hoist_inner_destructure : {{.*}} {
106+ // CHECK: {{bb[0-9]+}}([[S:%[^,]+]] :
107+ // CHECK: [[OUTER_COPY:%[^,]+]] = copy_value [[S]]
108+ // CHECK: [[S_BORROW:%[^,]+]] = begin_borrow [[S]]
109+ // CHECK: cond_br undef, [[LEFT:bb[0-9]+]], [[RIGHT:bb[0-9]+]]
110+ // CHECK: [[LEFT]]:
111+ // CHECK: [[INNARDS:%[^,]+]] = destructure_struct [[OUTER_COPY]]
112+ // CHECK: end_borrow [[S_BORROW]]
113+ // CHECK: destroy_value [[INNARDS]]
114+ // CHECK: destroy_value [[S]]
115+ // CHECK: br [[EXIT:bb[0-9]+]]
116+ // CHECK: [[RIGHT]]:
117+ // CHECK: destroy_value [[OUTER_COPY]]
118+ // CHECK: [[SINK:%[^,]+]] = function_ref @sink
119+ // CHECK: [[INNER_COPY:%[^,]+]] = copy_value [[S_BORROW]]
120+ // CHECK: apply [[SINK]]<S>([[INNER_COPY]])
121+ // CHECK: end_borrow [[S_BORROW]]
122+ // CHECK: destroy_value [[S]]
123+ // CHECK: br [[EXIT]]
124+ // CHECK: [[EXIT]]:
125+ // CHECK-LABEL: } // end sil function 'dont_hoist_inner_destructure'
126+ // CHECK-LABEL: end running test {{.*}} on dont_hoist_inner_destructure: canonicalize-borrow-scope
127+ sil [ossa] @dont_hoist_inner_destructure : $@convention(thin) (@owned S) -> () {
128+ entry(%s : @owned $S):
129+ test_specification "canonicalize-borrow-scope @instruction"
130+ %s_borrow = begin_borrow %s : $S
131+ %s_copy = copy_value %s_borrow : $S
132+ cond_br undef, left, right
133+
134+ left:
135+ %innards = destructure_struct %s_copy : $S
136+ end_borrow %s_borrow : $S
137+ destroy_value %innards : $SGuts
138+ destroy_value %s : $S
139+ br exit
140+
141+ right:
142+ %sink = function_ref @sink : $@convention(thin) <τ_0_0> (@owned τ_0_0) -> ()
143+ apply %sink<S>(%s_copy) : $@convention(thin) <τ_0_0> (@owned τ_0_0) -> ()
144+ end_borrow %s_borrow : $S
145+ destroy_value %s : $S
146+ br exit
147+
148+ exit:
149+ %retval = tuple ()
150+ return %retval : $()
151+ }
0 commit comments