@@ -93,3 +93,175 @@ bb0(%0 : $Builtin.NativeObject):
93
93
%9999 = tuple()
94
94
return %9999 : $()
95
95
}
96
+
97
+ //////////////////
98
+ // Assign Tests //
99
+ //////////////////
100
+
101
+ // Make sure that we do eliminate this allocation
102
+ // CHECK-LABEL: sil @simple_assign_take_trivial : $@convention(thin) (Builtin.Int32, @in Builtin.Int32) -> () {
103
+ // CHECK-NOT: alloc_stack
104
+ // CHECK: } // end sil function 'simple_assign_take_trivial'
105
+ sil @simple_assign_take_trivial : $@convention(thin) (Builtin.Int32, @in Builtin.Int32) -> () {
106
+ bb0(%0 : $Builtin.Int32, %1 : $*Builtin.Int32):
107
+ %2 = alloc_stack $Builtin.Int32
108
+ store %0 to %2 : $*Builtin.Int32
109
+ copy_addr [take] %1 to %2 : $*Builtin.Int32
110
+ dealloc_stack %2 : $*Builtin.Int32
111
+ %9999 = tuple()
112
+ return %9999 : $()
113
+ }
114
+
115
+ // In this case, we perform an init, copy. Since we do not want to lose the +1
116
+ // on the argument, we do not eliminate this (even though with time perhaps we
117
+ // could).
118
+ // CHECK-LABEL: sil @simple_init_copy : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
119
+ // CHECK: alloc_stack
120
+ // CHECK: copy_addr
121
+ // CHECK: } // end sil function 'simple_init_copy'
122
+ sil @simple_init_copy : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
123
+ bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
124
+ %2 = alloc_stack $Builtin.NativeObject
125
+ store %0 to %2 : $*Builtin.NativeObject
126
+ destroy_addr %2 : $*Builtin.NativeObject
127
+ copy_addr %1 to [initialization] %2 : $*Builtin.NativeObject
128
+ destroy_addr %2 : $*Builtin.NativeObject
129
+ dealloc_stack %2 : $*Builtin.NativeObject
130
+ %9999 = tuple()
131
+ return %9999 : $()
132
+ }
133
+
134
+ // This we can promote successfully.
135
+ // CHECK-LABEL: sil @simple_init_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
136
+ // CHECK: bb0([[ARG0:%.*]] : $Builtin.NativeObject, [[ARG1:%.*]] : $*Builtin.NativeObject):
137
+ // CHECK-NOT: alloc_stack
138
+ // CHECK: strong_release [[ARG0]]
139
+ // CHECK: [[ARG1_LOADED:%.*]] = load [[ARG1]]
140
+ // CHECK: strong_release [[ARG1_LOADED]]
141
+ // CHECK: } // end sil function 'simple_init_take'
142
+ sil @simple_init_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
143
+ bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
144
+ %2 = alloc_stack $Builtin.NativeObject
145
+ store %0 to %2 : $*Builtin.NativeObject
146
+ destroy_addr %2 : $*Builtin.NativeObject
147
+ copy_addr [take] %1 to [initialization] %2 : $*Builtin.NativeObject
148
+ destroy_addr %2 : $*Builtin.NativeObject
149
+ dealloc_stack %2 : $*Builtin.NativeObject
150
+ %9999 = tuple()
151
+ return %9999 : $()
152
+ }
153
+
154
+ // Since we are copying the input argument, we can not get rid of the copy_addr,
155
+ // meaning we shouldn't eliminate the allocation here.
156
+ // CHECK-LABEL: sil @simple_assign_no_take : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
157
+ // CHECK: alloc_stack
158
+ // CHECK: copy_addr
159
+ // CHECK: } // end sil function 'simple_assign_no_take'
160
+ sil @simple_assign_no_take : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
161
+ bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
162
+ %2 = alloc_stack $Builtin.NativeObject
163
+ store %0 to %2 : $*Builtin.NativeObject
164
+ copy_addr %1 to %2 : $*Builtin.NativeObject
165
+ destroy_addr %2 : $*Builtin.NativeObject
166
+ dealloc_stack %2 : $*Builtin.NativeObject
167
+ %9999 = tuple()
168
+ return %9999 : $()
169
+ }
170
+
171
+ // If PMO understood how to promote assigns, we should be able to handle this
172
+ // case.
173
+ // CHECK-LABEL: sil @simple_assign_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
174
+ // CHECK: alloc_stack
175
+ // CHECK: copy_addr
176
+ // CHECK: } // end sil function 'simple_assign_take'
177
+ sil @simple_assign_take : $@convention(thin) (@owned Builtin.NativeObject, @in Builtin.NativeObject) -> () {
178
+ bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
179
+ %2 = alloc_stack $Builtin.NativeObject
180
+ store %0 to %2 : $*Builtin.NativeObject
181
+ copy_addr [take] %1 to %2 : $*Builtin.NativeObject
182
+ destroy_addr %2 : $*Builtin.NativeObject
183
+ dealloc_stack %2 : $*Builtin.NativeObject
184
+ %9999 = tuple()
185
+ return %9999 : $()
186
+ }
187
+
188
+ // CHECK-LABEL: sil @simple_diamond_without_assign : $@convention(thin) (@owned Builtin.NativeObject) -> () {
189
+ // CHECK: bb0([[ARG:%.*]] :
190
+ // CHECK-NOT: alloc_stack
191
+ // CHECK-NOT: store
192
+ // CHECK: bb3:
193
+ // CHECK-NEXT: strong_release [[ARG]]
194
+ // CHECK: } // end sil function 'simple_diamond_without_assign'
195
+ sil @simple_diamond_without_assign : $@convention(thin) (@owned Builtin.NativeObject) -> () {
196
+ bb0(%0 : $Builtin.NativeObject):
197
+ %1 = alloc_stack $Builtin.NativeObject
198
+ store %0 to %1 : $*Builtin.NativeObject
199
+ cond_br undef, bb1, bb2
200
+
201
+ bb1:
202
+ br bb3
203
+
204
+ bb2:
205
+ br bb3
206
+
207
+ bb3:
208
+ destroy_addr %1 : $*Builtin.NativeObject
209
+ dealloc_stack %1 : $*Builtin.NativeObject
210
+ %9999 = tuple()
211
+ return %9999 : $()
212
+ }
213
+
214
+ // We should not promote this due to this being an assign to %2.
215
+ // CHECK-LABEL: sil @simple_diamond_with_assign : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
216
+ // CHECK: alloc_stack
217
+ // CHECK: copy_addr
218
+ // CHECK: } // end sil function 'simple_diamond_with_assign'
219
+ sil @simple_diamond_with_assign : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
220
+ bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
221
+ %2 = alloc_stack $Builtin.NativeObject
222
+ store %0 to %2 : $*Builtin.NativeObject
223
+ cond_br undef, bb1, bb2
224
+
225
+ bb1:
226
+ copy_addr [take] %1 to %2 : $*Builtin.NativeObject
227
+ br bb3
228
+
229
+ bb2:
230
+ br bb3
231
+
232
+ bb3:
233
+ destroy_addr %2 : $*Builtin.NativeObject
234
+ dealloc_stack %2 : $*Builtin.NativeObject
235
+ %9999 = tuple()
236
+ return %9999 : $()
237
+ }
238
+
239
+ // Today PMO can not handle different available values coming from different
240
+ // BBs. With time it can be taught to do that if necessary. That being said,
241
+ // this test shows that we /tried/ and failed with the available value test
242
+ // instead of failing earlier due to the copy_addr being an assign since we
243
+ // explode the copy_addr.
244
+ // CHECK-LABEL: sil @simple_diamond_with_assign_remove : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
245
+ // CHECK: alloc_stack
246
+ // CHECK-NOT: copy_addr
247
+ // CHECK: } // end sil function 'simple_diamond_with_assign_remove'
248
+ sil @simple_diamond_with_assign_remove : $@convention(thin) (@owned Builtin.NativeObject, @in_guaranteed Builtin.NativeObject) -> () {
249
+ bb0(%0 : $Builtin.NativeObject, %1 : $*Builtin.NativeObject):
250
+ %2 = alloc_stack $Builtin.NativeObject
251
+ store %0 to %2 : $*Builtin.NativeObject
252
+ cond_br undef, bb1, bb2
253
+
254
+ bb1:
255
+ destroy_addr %2 : $*Builtin.NativeObject
256
+ copy_addr [take] %1 to [initialization] %2 : $*Builtin.NativeObject
257
+ br bb3
258
+
259
+ bb2:
260
+ br bb3
261
+
262
+ bb3:
263
+ destroy_addr %2 : $*Builtin.NativeObject
264
+ dealloc_stack %2 : $*Builtin.NativeObject
265
+ %9999 = tuple()
266
+ return %9999 : $()
267
+ }
0 commit comments