1
- // RUN: %target-sil-opt -opt-mode=none -enable-sil-verify-all %s -ssa-destroy-hoisting | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECKDEB
2
- // RUN: %target-sil-opt -opt-mode=speed -enable-sil-verify-all %s -ssa-destroy-hoisting | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECKOPT
1
+ // RUN: %target-sil-opt -opt-mode=none -enable-sil-verify-all %s -ssa-destroy-hoisting | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECKDEB --check-prefix=CHECK-DEB
2
+ // RUN: %target-sil-opt -opt-mode=speed -enable-sil-verify-all %s -ssa-destroy-hoisting | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECKOPT --check-prefix=CHECK-OPT
3
3
//
4
4
// TODO: migrate the remaining tests from destroy_hoisting.sil.
5
5
@@ -188,9 +188,9 @@ bb0(%0 : $*T):
188
188
// bb2. Dead debug instructions then need to be deleted before the
189
189
// destroy can be merged back onto bb3.
190
190
//
191
- // CHECK-LABEL: sil hidden [ossa] @destroyDiamond : $@convention(thin) <T> (@in_guaranteed T, Builtin.Int1) -> () {
191
+ // CHECK-LABEL: sil hidden [ossa] @destroyDiamond_lexical : $@convention(thin) <T> (@in_guaranteed T, Builtin.Int1) -> () {
192
192
// CHECK: bb0(%0 : $*T, %1 : $Builtin.Int1):
193
- // CHECK: [[ALLOC:%.*]] = alloc_stack $T, var, name "t"
193
+ // CHECK: [[ALLOC:%.*]] = alloc_stack [lexical] $T, var, name "t"
194
194
// CHECK-NOT: destroy
195
195
// CHECK: cond_br %{{.*}}, bb1, bb2
196
196
// CHECK: bb1:
@@ -199,13 +199,60 @@ bb0(%0 : $*T):
199
199
// CHECK: br bb3
200
200
// CHECK: bb2:
201
201
// CHECKDEB: debug_value [[ALLOC]] : $*T, let, name "t"
202
- // CHECK-NOT: debug_val [[ALLOC]]
202
+ // CHECK-NOT: debug_value [[ALLOC]]
203
203
// CHECK: br bb3
204
204
// CHECK: bb3:
205
205
// CHECK: destroy_addr [[ALLOC]] : $*T
206
206
// CHECK: return
207
- // CHECK-LABEL: } // end sil function 'destroyDiamond'
208
- sil hidden [ossa] @destroyDiamond : $@convention(thin) <T> (@in_guaranteed T, Builtin.Int1) -> () {
207
+ // CHECK-LABEL: } // end sil function 'destroyDiamond_lexical'
208
+ sil hidden [ossa] @destroyDiamond_lexical : $@convention(thin) <T> (@in_guaranteed T, Builtin.Int1) -> () {
209
+ bb0(%0 : $*T, %1 : $Builtin.Int1):
210
+ debug_value %0 : $*T, let, name "arg", argno 1, expr op_deref
211
+ debug_value %1 : $Builtin.Int1, let, name "z", argno 2
212
+ %4 = alloc_stack [lexical] $T, var, name "t"
213
+ copy_addr %0 to [initialization] %4 : $*T
214
+ cond_br %1, bb1, bb2
215
+
216
+ bb1:
217
+ %8 = function_ref @unknown : $@convention(thin) () -> ()
218
+ %9 = apply %8() : $@convention(thin) () -> ()
219
+ br bb3
220
+
221
+ bb2:
222
+ debug_value %4 : $*T, let, name "t"
223
+ br bb3
224
+
225
+ bb3:
226
+ destroy_addr %4 : $*T
227
+ dealloc_stack %4 : $*T
228
+ %14 = tuple ()
229
+ return %14 : $()
230
+ }
231
+
232
+ // In contrast to the lexical variant (destroyDiamond_lexical), the destroy can
233
+ // be hoisted over the unknown apply. In the debug case, it can't be hoisted
234
+ // over the debug_value. In the optimized case, it can be hoisted up to the
235
+ // entry block.
236
+ //
237
+ // CHECK-LABEL: sil hidden [ossa] @destroyDiamond_nonlexical : $@convention(thin) <T> (@in_guaranteed T, Builtin.Int1) -> () {
238
+ // CHECK: {{bb[0-9]+}}
239
+ // CHECK: [[ALLOC:%.*]] = alloc_stack
240
+ // CHECK-OPT: destroy_addr [[ALLOC]]
241
+ // CHECK: cond_br %{{.*}}, [[LEFT:bb[0-9]+]], [[RIGHT:bb[0-9]+]]
242
+ // CHECK: [[LEFT]]:
243
+ // CHECK-DBG: destroy_addr [[ALLOC]]
244
+ // CHECK: apply %{{.*}}()
245
+ // CHECK-NOT: destroy_addr
246
+ // CHECK: br [[EXIT:bb[0-9]+]]
247
+ // CHECK: [[RIGHT]]:
248
+ // CHECK-OPT-NOT: debug_value [[ALLOC]]
249
+ // CHECK-DBG: debug_value [[ALLOC]]
250
+ // CHECK-DBG: destroy_addr [[ALLOC]]
251
+ // CHECK: br [[EXIT]]
252
+ // CHECK: [[EXIT]]:
253
+ // CHECK: return
254
+ // CHECK-LABEL: } // end sil function 'destroyDiamond_nonlexical'
255
+ sil hidden [ossa] @destroyDiamond_nonlexical : $@convention(thin) <T> (@in_guaranteed T, Builtin.Int1) -> () {
209
256
bb0(%0 : $*T, %1 : $Builtin.Int1):
210
257
debug_value %0 : $*T, let, name "arg", argno 1, expr op_deref
211
258
debug_value %1 : $Builtin.Int1, let, name "z", argno 2
229
276
return %14 : $()
230
277
}
231
278
232
- // CHECK-LABEL: sil hidden [ossa] @destroyLoop : $@convention(thin) <T> (@in_guaranteed T) -> () {
233
- // CHECK: [[ALLOC:%.*]] = alloc_stack $T, var, name "t"
279
+ // CHECK-LABEL: sil hidden [ossa] @destroyLoop_lexical : $@convention(thin) <T> (@in_guaranteed T) -> () {
280
+ // CHECK: [[ALLOC:%.*]] = alloc_stack [lexical] $T, var, name "t"
234
281
// CHECK: br bb1
235
282
// CHECK: bb1:
236
283
// CHECK: apply %{{.*}}() : $@convention(thin) () -> Builtin.Int1
@@ -242,8 +289,45 @@ bb3:
242
289
// CHECKOPT-NOT: debug_value
243
290
// CHECK: destroy_addr [[ALLOC]] : $*T
244
291
// CHECK: dealloc_stack [[ALLOC]] : $*T
245
- // CHECK-LABEL: } // end sil function 'destroyLoop'
246
- sil hidden [ossa] @destroyLoop : $@convention(thin) <T> (@in_guaranteed T) -> () {
292
+ // CHECK-LABEL: } // end sil function 'destroyLoop_lexical'
293
+ sil hidden [ossa] @destroyLoop_lexical : $@convention(thin) <T> (@in_guaranteed T) -> () {
294
+ bb0(%0 : $*T):
295
+ %a = alloc_stack [lexical] $T, var, name "t"
296
+ copy_addr %0 to [initialization] %a : $*T
297
+ br bb1
298
+
299
+ bb1:
300
+ %f = function_ref @f_bool : $@convention(thin) () -> Builtin.Int1
301
+ %c = apply %f() : $@convention(thin) () -> Builtin.Int1
302
+ cond_br %c, bb2, bb3
303
+
304
+ bb2:
305
+ br bb1
306
+
307
+ bb3:
308
+ debug_value %a : $*T, let, name "t"
309
+ destroy_addr %a : $*T
310
+ dealloc_stack %a : $*T
311
+ %16 = tuple ()
312
+ return %16 : $()
313
+ }
314
+
315
+ // CHECK-LABEL: sil hidden [ossa] @destroyLoop_nonlexical : $@convention(thin) <T> (@in_guaranteed T) -> () {
316
+ // CHECK: [[ALLOC:%.*]] = alloc_stack $T, var, name "t"
317
+ // CHECK-OPT: destroy_addr [[ALLOC]]
318
+ // CHECK: br bb1
319
+ // CHECK: bb1:
320
+ // CHECK: apply %{{.*}}() : $@convention(thin) () -> Builtin.Int1
321
+ // CHECK-NEXT: cond_br %{{.*}}, bb2, bb3
322
+ // CHECK: bb2:
323
+ // CHECK-NEXT: br bb1
324
+ // CHECK: bb3:
325
+ // CHECK-DEB: debug_value [[ALLOC]] : $*T, let, name "t"
326
+ // CHECK-OPT-NOT: debug_value
327
+ // CHECK-DEB: destroy_addr [[ALLOC]] : $*T
328
+ // CHECK: dealloc_stack [[ALLOC]] : $*T
329
+ // CHECK-LABEL: } // end sil function 'destroyLoop_nonlexical'
330
+ sil hidden [ossa] @destroyLoop_nonlexical : $@convention(thin) <T> (@in_guaranteed T) -> () {
247
331
bb0(%0 : $*T):
248
332
%a = alloc_stack $T, var, name "t"
249
333
copy_addr %0 to [initialization] %a : $*T
@@ -352,11 +436,34 @@ exit:
352
436
// unreachable-at-begin block is added to the worklist but its predecessor
353
437
// isn't discovered.
354
438
//
355
- // CHECK-LABEL: sil [ossa] @undiscovered_predecessor_of_unreachable_at_begin : {{.*}} {
439
+ // CHECK-LABEL: sil [ossa] @undiscovered_predecessor_of_unreachable_at_begin_lexical : {{.*}} {
356
440
// CHECK: apply undef
357
441
// CHECK-NEXT: destroy_addr
358
- // CHECK-LABEL: } // end sil function 'undiscovered_predecessor_of_unreachable_at_begin'
359
- sil [ossa] @undiscovered_predecessor_of_unreachable_at_begin : $@convention(thin) (@owned S) -> () {
442
+ // CHECK-LABEL: } // end sil function 'undiscovered_predecessor_of_unreachable_at_begin_lexical'
443
+ sil [ossa] @undiscovered_predecessor_of_unreachable_at_begin_lexical : $@convention(thin) (@owned S) -> () {
444
+ entry(%instance : @owned $S):
445
+ %addr = alloc_stack [lexical] $S
446
+ store %instance to [init] %addr : $*S
447
+ br applier
448
+
449
+ applier:
450
+ apply undef() : $@convention(thin) () -> ()
451
+ br good
452
+
453
+ good:
454
+ destroy_addr %addr : $*S
455
+ dealloc_stack %addr : $*S
456
+ %retval = tuple ()
457
+ return %retval : $()
458
+ }
459
+
460
+ // In contrast to the lexical case (undiscovered_predecessor_of_unreachable_at_begin_lexical)
461
+ //
462
+ // CHECK-LABEL: sil [ossa] @undiscovered_predecessor_of_unreachable_at_begin_nonlexical : {{.*}} {
463
+ // CHECK: store
464
+ // CHECK-NEXT: destroy_addr
465
+ // CHECK-LABEL: } // end sil function 'undiscovered_predecessor_of_unreachable_at_begin_nonlexical'
466
+ sil [ossa] @undiscovered_predecessor_of_unreachable_at_begin_nonlexical : $@convention(thin) (@owned S) -> () {
360
467
entry(%instance : @owned $S):
361
468
%addr = alloc_stack $S
362
469
store %instance to [init] %addr : $*S
@@ -545,10 +652,32 @@ entry(%instance : @owned $S):
545
652
546
653
// Don't fold when there's a deinit barrier in the way.
547
654
//
548
- // CHECK-LABEL: sil [ossa] @nofold_scoped_load_barrier : {{.*}} {
655
+ // CHECK-LABEL: sil [ossa] @nofold_scoped_load_barrier_lexical : {{.*}} {
549
656
// CHECK: load [copy]
550
- // CHECK-LABEL: // end sil function 'nofold_scoped_load_barrier'
551
- sil [ossa] @nofold_scoped_load_barrier : $@convention(thin) (@owned S) -> (@owned S) {
657
+ // CHECK-LABEL: // end sil function 'nofold_scoped_load_barrier_lexical'
658
+ sil [ossa] @nofold_scoped_load_barrier_lexical : $@convention(thin) (@owned S) -> (@owned S) {
659
+ entry(%instance : @owned $S):
660
+ %addr = alloc_stack [lexical] $S
661
+ %store_scope = begin_access [modify] [static] %addr : $*S
662
+ store %instance to [init] %store_scope : $*S
663
+ end_access %store_scope : $*S
664
+ %load_scope = begin_access [read] [static] %addr : $*S
665
+ %value = load [copy] %load_scope : $*S
666
+ %unknown = function_ref @unknown : $@convention(thin) () -> ()
667
+ apply %unknown() : $@convention(thin) () -> ()
668
+ end_access %load_scope : $*S
669
+ destroy_addr %addr : $*S
670
+ dealloc_stack %addr : $*S
671
+ return %value : $S
672
+ }
673
+
674
+ // Fold when there's a deinit barrier in the way if the alloc_stack is
675
+ // non-lexical.
676
+ //
677
+ // CHECK-LABEL: sil [ossa] @nofold_scoped_load_barrier_nonlexical : {{.*}} {
678
+ // CHECK: load [take]
679
+ // CHECK-LABEL: // end sil function 'nofold_scoped_load_barrier_nonlexical'
680
+ sil [ossa] @nofold_scoped_load_barrier_nonlexical : $@convention(thin) (@owned S) -> (@owned S) {
552
681
entry(%instance : @owned $S):
553
682
%addr = alloc_stack $S
554
683
%store_scope = begin_access [modify] [static] %addr : $*S
@@ -647,8 +776,8 @@ entry(%instance : @owned $S):
647
776
sil [ossa] @nofold_unrelated_scoped_load_copy : $@convention(thin) (@owned X) -> (@owned X) {
648
777
entry(%instance : @owned $X):
649
778
%copy = copy_value %instance : $X
650
- %addr_1 = alloc_stack $X
651
- %addr_2 = alloc_stack $X
779
+ %addr_1 = alloc_stack [lexical] $X
780
+ %addr_2 = alloc_stack [lexical] $X
652
781
store %instance to [init] %addr_1 : $*X
653
782
store %copy to [init] %addr_2 : $*X
654
783
0 commit comments