@@ -29,7 +29,9 @@ class PointerWrapper {
2929enum OneOfThree { case one, two, three }
3030
3131sil [ossa] @callee_guaranteed: $@convention(thin) (@guaranteed C) -> ()
32+ sil [ossa] @callee_owned : $@convention(thin) (@owned C) -> ()
3233sil [ossa] @callee_optional_d_guaranteed: $@convention(thin) (@guaranteed Optional<D>) -> ()
34+ sil [ossa] @synchronization_point : $@convention(thin) () -> ()
3335
3436// =============================================================================
3537// = DECLARATIONS }}
501503// CHECK: load_weak
502504// CHECK: end_borrow
503505// CHECK-LABEL: } // end sil function 'dont_hoist_over_load_weak'
504-
505506sil [ossa] @dont_hoist_over_load_weak : $@convention(thin) (@owned DBox) -> () {
506507entry(%instance : @owned $DBox):
507508 %lifetime = begin_borrow [lexical] %instance : $DBox
@@ -531,6 +532,137 @@ entry(%instance : @owned $DBox):
531532// before the deinit that would dealocated the pointed-to object, it must always
532533// remain first.
533534
535+ // Hoist over and rewrite copy of borrow.
536+ //
537+ // Everything in this test case except the copy_value and end_borrow is here in
538+ // order to obstruct other optimizations from kicking in that obfuscate that the
539+ // fact that the end_borrow was hoisted over the copy_value.
540+ // CHECK-LABEL: sil [ossa] @hoist_over_copy_of_borrow : {{.*}} {
541+ // CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @guaranteed $C):
542+ // CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[INSTANCE]]
543+ // CHECK: end_borrow [[LIFETIME]]
544+ // CHECK: {{%[^,]+}} = copy_value [[INSTANCE]]
545+ // CHECK-LABEL: } // end sil function 'hoist_over_copy_of_borrow'
546+ sil [ossa] @hoist_over_copy_of_borrow : $@convention(thin) (@guaranteed C) -> () {
547+ entry(%instance : @guaranteed $C):
548+ %lifetime = begin_borrow [lexical] %instance : $C
549+ %callee_guaranteed = function_ref @callee_guaranteed : $@convention(thin) (@guaranteed C) -> ()
550+ %_ = apply %callee_guaranteed(%lifetime) : $@convention(thin) (@guaranteed C) -> ()
551+ %synchronization_point = function_ref @synchronization_point : $@convention(thin) () -> ()
552+ %synchronized = apply %synchronization_point() : $@convention(thin) () -> ()
553+ %copy = copy_value %instance : $C
554+ end_borrow %lifetime : $C
555+ %callee_owned = function_ref @callee_owned : $@convention(thin) (@owned C) -> ()
556+ %2 = apply %callee_owned(%copy) : $@convention(thin) (@owned C) -> ()
557+ %result = tuple ()
558+ return %result : $()
559+ }
560+
561+ // Hoist over an apply that uses a copy of the borrow.
562+ // CHECK-LABEL: sil [ossa] @hoist_over_apply_at_copy : {{.*}} {
563+ // CHECK-NOT: copy_value
564+ // CHECK-LABEL: // end sil function 'hoist_over_apply_at_copy'
565+ sil [ossa] @hoist_over_apply_at_copy : $@convention(thin) (@owned C) -> () {
566+ entry(%instance : @owned $C):
567+ %synchronization_point = function_ref @synchronization_point : $@convention(thin) () -> ()
568+ %callee_owned = function_ref @callee_owned : $@convention(thin) (@owned C) -> ()
569+ %callee_guaranteed = function_ref @callee_guaranteed : $@convention(thin) (@guaranteed C) -> ()
570+ %lifetime = begin_borrow %instance : $C
571+ %copy = copy_value %lifetime : $C
572+ %1 = apply %callee_guaranteed(%copy) : $@convention(thin) (@guaranteed C) -> ()
573+ %synchronized = apply %synchronization_point() : $@convention(thin) () -> ()
574+ %2 = apply %callee_guaranteed(%copy) : $@convention(thin) (@guaranteed C) -> ()
575+ end_borrow %lifetime : $C
576+ destroy_value %instance : $C
577+ destroy_value %copy : $C
578+
579+ %result = tuple ()
580+ return %result : $()
581+ }
582+
583+ // Hoist over an apply that uses the borrow.
584+ // CHECK-LABEL: sil [ossa] @hoist_over_apply_at_borrow : {{.*}} {
585+ // CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C):
586+ // CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [[INSTANCE]]
587+ // CHECK: end_borrow [[LIFETIME]]
588+ // CHECK: apply {{%[^,]+}}([[INSTANCE]])
589+ // CHECK-LABEL: // end sil function 'hoist_over_apply_at_borrow'
590+ sil [ossa] @hoist_over_apply_at_borrow : $@convention(thin) (@owned C) -> () {
591+ entry(%instance : @owned $C):
592+ %lifetime = begin_borrow %instance : $C
593+ %copy = copy_value %lifetime : $C
594+ %callee_owned = function_ref @callee_owned : $@convention(thin) (@owned C) -> ()
595+ %callee_guaranteed = function_ref @callee_guaranteed : $@convention(thin) (@guaranteed C) -> ()
596+ %1 = apply %callee_owned(%copy) : $@convention(thin) (@owned C) -> ()
597+ %synchronization_point = function_ref @synchronization_point : $@convention(thin) () -> ()
598+ %synchronized = apply %synchronization_point() : $@convention(thin) () -> ()
599+ %2 = apply %callee_guaranteed(%lifetime) : $@convention(thin) (@guaranteed C) -> ()
600+ end_borrow %lifetime : $C
601+ destroy_value %instance : $C
602+
603+ %result = tuple ()
604+ return %result : $()
605+ }
606+
607+ // Hoist over a begin_borrow of a copy_value of the original begin_borrow.
608+ //
609+ // Most of the test's contents are just to obstruct optimization.
610+ // CHECK-LABEL: sil [ossa] @hoist_over_borrow_of_copy : {{.*}} {
611+ // CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C):
612+ // CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [[INSTANCE]]
613+ // CHECK: [[COPY:%[^,]+]] = copy_value [[LIFETIME]]
614+ // CHECK: end_borrow [[LIFETIME]]
615+ // CHECK: begin_borrow [[COPY]]
616+ // CHECK-LABEL: // end sil function 'hoist_over_borrow_of_copy'
617+ sil [ossa] @hoist_over_borrow_of_copy : $@convention(thin) (@owned C) -> () {
618+ entry(%instance : @owned $C):
619+ %lifetime_1 = begin_borrow %instance : $C
620+ %copy_1 = copy_value %lifetime_1 : $C
621+ %callee_guaranteed = function_ref @callee_guaranteed : $@convention(thin) (@guaranteed C) -> ()
622+ %1 = apply %callee_guaranteed(%copy_1) : $@convention(thin) (@guaranteed C) -> ()
623+ %synchronization_point = function_ref @synchronization_point : $@convention(thin) () -> ()
624+ %synchronized = apply %synchronization_point() : $@convention(thin) () -> ()
625+ %lifetime_2 = begin_borrow %copy_1 : $C
626+ end_borrow %lifetime_1 : $C
627+ %copy_2 = copy_value %lifetime_2 : $C
628+ %2 = apply %callee_guaranteed(%copy_2) : $@convention(thin) (@guaranteed C) -> ()
629+ %synchronized2 = apply %synchronization_point() : $@convention(thin) () -> ()
630+ end_borrow %lifetime_2 : $C
631+ destroy_value %copy_1 : $C
632+ destroy_value %copy_2 : $C
633+ destroy_value %instance : $C
634+
635+ %result = tuple ()
636+ return %result : $()
637+ }
638+
639+ // Hoist over copy_value of %copy, a copy_value of %borrow.
640+ // CHECK-LABEL: sil [ossa] @hoist_over_copy_of_copy : {{.*}} {
641+ // CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C):
642+ // CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [[INSTANCE]] : $C
643+ // CHECK: [[COPY_1:%[^,]+]] = copy_value [[LIFETIME]] : $C
644+ // CHECK: end_borrow [[LIFETIME]] : $C
645+ // CHECK: copy_value [[INSTANCE]] : $C
646+ // CHECK-LABEL: } // end sil function 'hoist_over_copy_of_copy'
647+ sil [ossa] @hoist_over_copy_of_copy : $@convention(thin) (@owned C) -> () {
648+ entry(%instance : @owned $C):
649+ %synchronization_point = function_ref @synchronization_point : $@convention(thin) () -> ()
650+ %callee_guaranteed = function_ref @callee_guaranteed : $@convention(thin) (@guaranteed C) -> ()
651+ %callee_owned = function_ref @callee_owned : $@convention(thin) (@owned C) -> ()
652+ %lifetime_1 = begin_borrow %instance : $C
653+ %copy_1 = copy_value %lifetime_1 : $C
654+ %_ = apply %callee_guaranteed(%lifetime_1) : $@convention(thin) (@guaranteed C) -> ()
655+ %synchronized = apply %synchronization_point() : $@convention(thin) () -> ()
656+ %copy_2 = copy_value %copy_1 : $C
657+ end_borrow %lifetime_1 : $C
658+ %0 = apply %callee_owned(%instance) : $@convention(thin) (@owned C) -> ()
659+ %1 = apply %callee_owned(%copy_1) : $@convention(thin) (@owned C) -> ()
660+ %2 = apply %callee_owned(%copy_2) : $@convention(thin) (@owned C) -> ()
661+
662+ %result = tuple ()
663+ return %result : $()
664+ }
665+
534666// =============================================================================
535667// instruction tests }}
536668// =============================================================================
0 commit comments