1
1
// RUN: %target-sil-opt -enable-sil-verify-all %s -jumpthread-simplify-cfg -enable-ossa-simplify-cfg -enable-ossa-rewriteterminator | %FileCheck %s
2
2
// RUN: %target-sil-opt -enable-sil-verify-all %s -jumpthread-simplify-cfg -enable-ossa-simplify-cfg -enable-ossa-rewriteterminator -debug-only=sil-simplify-cfg 2>&1 | %FileCheck %s --check-prefix=CHECK-TRACE
3
3
//
4
- // REQUIRES: EnableOSSASimplifyCFG
4
+ // REQUIRES!!! : EnableOSSASimplifyCFG
5
5
6
6
// FIXME: When OSSA optimization is complete, convert XCHECK to CHECK lines
7
7
@@ -46,6 +46,8 @@ class Final : Derived {
46
46
sil [ossa] @_TFC3ccb4Base5innerfS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
47
47
sil [ossa] @_TFC3ccb4Base6middlefS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
48
48
49
+ sil @get_base : $@convention(thin) () -> @owned Base
50
+
49
51
// CHECK-LABEL: sil [ossa] @redundant_checked_cast_br
50
52
sil [ossa] @redundant_checked_cast_br : $@convention(method) (@guaranteed Base) -> () {
51
53
bb0(%0 : @guaranteed $Base):
@@ -324,6 +326,7 @@ bb5(%2a : @guaranteed $Base):
324
326
br bb6
325
327
326
328
bb6:
329
+ dealloc_ref %a : $Base
327
330
dealloc_stack_ref %a : $Base
328
331
%r = tuple()
329
332
return %r : $()
@@ -402,7 +405,7 @@ bb0(%0 : @guaranteed $Klass):
402
405
%4 = copy_value %3 : $Klass
403
406
checked_cast_br %3 : $Klass to OtherKlass, bb1, bb2
404
407
405
- bb1(%5 : $OtherKlass):
408
+ bb1(%5 : @owned $OtherKlass):
406
409
destroy_value %5 : $OtherKlass
407
410
%6 = integer_literal $Builtin.Int1, -1
408
411
br bb3(%6 : $Builtin.Int1)
@@ -428,19 +431,20 @@ bb6:
428
431
bb7(%16 : @owned $Klass):
429
432
checked_cast_br %16 : $Klass to OtherKlass, bb9, bb8
430
433
431
- bb8(%18 : $Klass):
434
+ bb8(%18 : @owned $Klass):
432
435
destroy_value %18 : $Klass
433
436
br bb4
434
437
435
- bb9(%20 : $OtherKlass):
438
+ bb9(%20 : @owned $OtherKlass):
436
439
return %20 : $OtherKlass
437
440
438
441
bb10(%22 : $Builtin.Int64):
439
442
%23 = apply %1() : $@convention(thin) () -> @owned Klass
440
443
%24 = copy_value %23 : $Klass
441
444
checked_cast_br %23 : $Klass to OtherKlass, bb11, bb12
442
445
443
- bb11(%25 : $OtherKlass):
446
+ bb11(%25 : @owned $OtherKlass):
447
+ destroy_value %25 : $OtherKlass
444
448
%26 = integer_literal $Builtin.Int1, -1
445
449
br bb13(%26 : $Builtin.Int1)
446
450
@@ -465,3 +469,215 @@ bb16:
465
469
bb17:
466
470
br bb10(undef : $Builtin.Int64)
467
471
}
472
+
473
+ // =============================================================================
474
+ // Test OSSA lifetime fixup after removing redundant checked_cast_br
475
+
476
+ // Replace an owned result with a guaranteed value on the success path.
477
+ // Introduce a copy for the new lifetime.
478
+ //
479
+ // CHECK-LABEL: sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_success : $@convention(method) (@owned Base) -> () {
480
+ // CHECK: bb0(%0 : @owned $Base):
481
+ // CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Base
482
+ // CHECK: checked_cast_br [exact] [[BORROW]] : $Base to Base, bb1, bb2
483
+ // CHECK: bb1([[EXACT:%.*]] : @guaranteed $Base):
484
+ // CHECK-NEXT: [[NEWCP:%.*]] = copy_value [[EXACT]] : $Base
485
+ // CHECK-NEXT: [[OLDCP:%.*]] = copy_value [[EXACT]] : $Base
486
+ // CHECK-NEXT: end_borrow
487
+ // CHECK: destroy_value [[OLDCP]] : $Base
488
+ // CHECK: apply %{{.*}}([[NEWCP]]) : $@convention(method) (@guaranteed Base) -> ()
489
+ // CHECK: destroy_value [[NEWCP]] : $Base
490
+ // CHECK: br bb3
491
+ // CHECK: bb2([[INEXACT:%.*]] : @guaranteed $Base):
492
+ // CHECK: apply %{{.*}}([[INEXACT]]) : $@convention(method) (@guaranteed Base) -> ()
493
+ // CHECK: end_borrow %1 : $Base
494
+ // CHECK: br bb3
495
+ // CHECK: bb3:
496
+ // CHECK: destroy_value %0 : $Base
497
+ // CHECK-LABEL: } // end sil function 'redundant_checked_cast_br_rauw_guaranteed_to_owned_success'
498
+ sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_success : $@convention(method) (@owned Base) -> () {
499
+ bb0(%0 : @owned $Base):
500
+ %borrow = begin_borrow %0 : $Base
501
+ %1 = class_method %0 : $Base, #Base.middle : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
502
+ checked_cast_br [exact] %borrow : $Base to Base, bb1, bb6
503
+
504
+ bb1(%5 : @guaranteed $Base):
505
+ %6 = copy_value %5 : $Base
506
+ end_borrow %borrow : $Base
507
+ %7 = class_method %0 : $Base, #Base.inner : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
508
+ checked_cast_br [exact] %6 : $Base to Base, bb2, bb4
509
+
510
+ bb2(%9 : @owned $Base):
511
+ %10 = function_ref @_TFC3ccb4Base5innerfS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
512
+ %11 = apply %10(%9) : $@convention(method) (@guaranteed Base) -> ()
513
+ destroy_value %9 : $Base
514
+ br bb3
515
+
516
+ bb3:
517
+ %13 = tuple ()
518
+ br bb5(%13 : $())
519
+
520
+ bb4(%defaultBB2 : @owned $Base):
521
+ %15 = apply %7(%defaultBB2) : $@convention(method) (@guaranteed Base) -> ()
522
+ destroy_value %defaultBB2 : $Base
523
+ br bb3
524
+
525
+ bb5(%17 : $()):
526
+ br bb7
527
+
528
+ bb6(%defaultBB0 : @guaranteed $Base):
529
+ %19 = apply %1(%defaultBB0) : $@convention(method) (@guaranteed Base) -> ()
530
+ end_borrow %borrow : $Base
531
+ br bb7
532
+
533
+ bb7:
534
+ destroy_value %0 : $Base
535
+ %3 = tuple ()
536
+ return %3 : $()
537
+ }
538
+
539
+ // Replace an owned result with a guaranteed value on the merged path.
540
+ // Introduce a copy for the new lifetime.
541
+ // Simplify down to a single diamond.
542
+ //
543
+ // TODO: Simplify some of the obvisouly dead copy/destroy/borrows
544
+ // on-the-fly after each simplify-cfg. Possible using CanonicalizeOSSALifetime.
545
+ //
546
+ // CHECK-LABEL: sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_merge : $@convention(method) (@owned Base) -> () {
547
+ // CHECK: bb0(%0 : @owned $Base):
548
+ // CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Base
549
+ // CHECK: checked_cast_br [exact] [[BORROW]] : $Base to Base, bb1, bb3
550
+ // CHECK: bb1([[ARG1:%.*]] : @guaranteed $Base):
551
+ // CHECK: [[NEWCOPY1:%.*]] = copy_value [[ARG1]] : $Base
552
+ // CHECK: apply %{{.*}}([[ARG1]]) : $@convention(method) (@guaranteed Base) -> ()
553
+ // CHECK: [[OLDCOPY:%.*]] = copy_value [[BORROW]] : $Base
554
+ // CHECK: end_borrow [[BORROW]] : $Base
555
+ // CHECK: destroy_value [[OLDCOPY]] : $Base
556
+ // CHECK: apply %{{.*}}([[NEWCOPY1]]) : $@convention(method) (@guaranteed Base) -> ()
557
+ // CHECK: destroy_value [[NEWCOPY1]] : $Base
558
+ // CHECK: br bb2
559
+ // CHECK: bb2:
560
+ // CHECK: destroy_value %0 : $Base
561
+ // CHECK: return
562
+ // CHECK: bb3([[ARG3:%.*]] : @guaranteed $Base):
563
+ // CHECK: apply %1([[ARG3]]) : $@convention(method) (@guaranteed Base) -> ()
564
+ // CHECK: [[NEWCOPY3:%.*]] = copy_value [[BORROW]] : $Base
565
+ // CHECK: end_borrow [[BORROW]] : $Base
566
+ // CHECK: apply %{{.*}}([[NEWCOPY3]]) : $@convention(method) (@guaranteed Base) -> ()
567
+ // CHECK: destroy_value [[NEWCOPY3]] : $Base
568
+ // CHECK: br bb2
569
+ // CHECK-LABEL: } // end sil function 'redundant_checked_cast_br_rauw_guaranteed_to_owned_merge'
570
+ sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_merge : $@convention(method) (@owned Base) -> () {
571
+ bb0(%0 : @owned $Base):
572
+ %m = class_method %0 : $Base, #Base.inner : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
573
+ %f = function_ref @_TFC3ccb4Base5innerfS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
574
+ %1 = begin_borrow %0 : $Base
575
+ checked_cast_br [exact] %1 : $Base to Base, bb1, bb2
576
+
577
+ bb1(%4 : @guaranteed $Base):
578
+ %5 = apply %f(%4) : $@convention(method) (@guaranteed Base) -> ()
579
+ br bb3
580
+
581
+ bb2(%7 : @guaranteed $Base):
582
+ %8 = apply %m(%7) : $@convention(method) (@guaranteed Base) -> ()
583
+ br bb3
584
+
585
+ bb3:
586
+ %11 = copy_value %1 : $Base
587
+ end_borrow %1 : $Base
588
+ checked_cast_br [exact] %11 : $Base to Base, bb4, bb5
589
+
590
+ bb4(%14 : @owned $Base):
591
+ %15 = apply %f(%14) : $@convention(method) (@guaranteed Base) -> ()
592
+ destroy_value %14 : $Base
593
+ br bb6
594
+
595
+ bb5(%20 : @owned $Base):
596
+ %21 = apply %m(%20) : $@convention(method) (@guaranteed Base) -> ()
597
+ destroy_value %20 : $Base
598
+ br bb6
599
+
600
+ bb6:
601
+ destroy_value %0 : $Base
602
+ %27 = tuple ()
603
+ return %27 : $()
604
+ }
605
+
606
+ // Replace an owned result with a guaranteed value on the merged path.
607
+ //
608
+ // The merged path has an unknown predecessor, where the merged value
609
+ // is produced by an apply.
610
+ //
611
+ // Clone the success path, introducing a copy on it.
612
+ //
613
+ // CHECK-LABEL: sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_mergecopy : $@convention(method) (@owned Base) -> () {
614
+ // CHECK: bb0(%0 : @owned $Base):
615
+ // CHECK: [[BORROW:%.*]] = begin_borrow %0 : $Base
616
+ // CHECK: checked_cast_br [exact] [[BORROW]] : $Base to Base, bb1, bb2
617
+ // CHECK: bb1([[ARG1:%.*]] : @guaranteed $Base):
618
+ // CHECK: [[CP1:%.*]] = copy_value [[ARG1]] : $Base
619
+ // CHECK: apply %2([[ARG1]]) : $@convention(method) (@guaranteed Base) -> ()
620
+ // CHECK: end_borrow [[BORROW]] : $Base
621
+ // CHECK: br bb4([[CP1]] : $Base)
622
+ // CHECK: bb2([[ARG2:%.*]] : @guaranteed $Base):
623
+ // CHECK: apply %{{.*}}([[ARG2]]) : $@convention(method) (@guaranteed Base) -> ()
624
+ // CHECK: [[RESULT:%.*]] = apply %{{.*}}() : $@convention(thin) () -> @owned Base
625
+ // CHECK: end_borrow [[BORROW]] : $Base
626
+ // CHECK: checked_cast_br [exact] %13 : $Base to Base, bb3, bb5
627
+ // CHECK: bb3([[ARG3:%.*]] : @owned $Base):
628
+ // CHECK: br bb4(%16 : $Base)
629
+ // CHECK: bb4([[ARG4:%.*]] : @owned $Base):
630
+ // CHECK: apply %{{.*}}([[ARG4]]) : $@convention(method) (@guaranteed Base) -> ()
631
+ // CHECK: destroy_value [[ARG4]] : $Base
632
+ // CHECK: br bb6
633
+ // CHECK: bb5([[ARG5:%.*]] : @owned $Base):
634
+ // CHECK: apply %{{.*}}([[ARG5]]) : $@convention(method) (@guaranteed Base) -> ()
635
+ // CHECK: destroy_value [[ARG5]] : $Base
636
+ // CHECK: br bb6
637
+ // CHECK: bb6:
638
+ // CHECK: destroy_value %0 : $Base
639
+ // CHECK: return
640
+ // CHECK-LABEL: } // end sil function 'redundant_checked_cast_br_rauw_guaranteed_to_owned_mergecopy'
641
+ sil [ossa] @redundant_checked_cast_br_rauw_guaranteed_to_owned_mergecopy : $@convention(method) (@owned Base) -> () {
642
+ bb0(%0 : @owned $Base):
643
+ %1 = class_method %0 : $Base, #Base.inner : (Base) -> () -> (), $@convention(method) (@guaranteed Base) -> ()
644
+
645
+ %2 = function_ref @_TFC3ccb4Base5innerfS0_FT_T_ : $@convention(method) (@guaranteed Base) -> ()
646
+ %f = function_ref @get_base : $@convention(thin) () -> @owned Base
647
+ %3 = begin_borrow %0 : $Base
648
+ checked_cast_br [exact] %3 : $Base to Base, bb1, bb2
649
+
650
+ bb1(%6 : @guaranteed $Base):
651
+ %7 = apply %2(%6) : $@convention(method) (@guaranteed Base) -> ()
652
+ %8 = copy_value %6 : $Base
653
+ br bb3(%8 : $Base)
654
+
655
+ bb2(%9 : @guaranteed $Base):
656
+ %10 = apply %1(%9) : $@convention(method) (@guaranteed Base) -> ()
657
+ %11 = apply %f() : $@convention(thin) () -> @owned Base
658
+ br bb3(%11 : $Base)
659
+
660
+ bb3(%12 : @owned $Base):
661
+ end_borrow %3 : $Base
662
+ checked_cast_br [exact] %12 : $Base to Base, bb6, bb7
663
+
664
+ bb6(%16 : @owned $Base):
665
+ %17 = apply %2(%16) : $@convention(method) (@guaranteed Base) -> ()
666
+ destroy_value %16 : $Base
667
+ br bb8
668
+
669
+ bb7(%20 : @owned $Base):
670
+ %21 = apply %1(%20) : $@convention(method) (@guaranteed Base) -> ()
671
+ destroy_value %20 : $Base
672
+ br bb8
673
+
674
+ bb8:
675
+ destroy_value %0 : $Base
676
+ %25 = tuple ()
677
+ return %25 : $()
678
+ }
679
+
680
+ //!!!TODO: test replacing a guaranteed value with an ownedvalue
681
+ // test borrowOverValue->borrowCopyOverScope path
682
+
683
+ //!!!TODO: test prepareUnowned paths
0 commit comments