@@ -21,9 +21,18 @@ protocol Addable {
21
21
22
22
// Class declarations
23
23
24
+ struct NativeObjectWrapper {
25
+ var obj: Builtin.NativeObject
26
+ }
27
+
28
+ sil @inguaranteed_nativeobject_user : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
29
+
24
30
class Klass {
25
31
init()
26
32
deinit
33
+
34
+ var field: Klass
35
+ var structField: NativeObjectWrapper
27
36
}
28
37
29
38
class SubKlass : Klass {}
@@ -667,3 +676,300 @@ bb3(%4 : @owned $FakeOptional<Klass>):
667
676
%9999 = tuple()
668
677
return %9999 : $()
669
678
}
679
+
680
+ // CHECK-LABEL: sil [ossa] @interior_pointer_lifetime_extension_arg_not_int_ptr : $@convention(thin) (@in_guaranteed Klass) -> @owned Klass {
681
+ // CHECK-NOT: address_to_pointer
682
+ // CHECK-NOT: pointer_to_address
683
+ // CHECK: } // end sil function 'interior_pointer_lifetime_extension_arg_not_int_ptr'
684
+ sil [ossa] @interior_pointer_lifetime_extension_arg_not_int_ptr : $@convention(thin) (@in_guaranteed Klass) -> @owned Klass {
685
+ bb0(%0 : $*Klass):
686
+ %1 = address_to_pointer %0 : $*Klass to $Builtin.RawPointer
687
+ %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Klass
688
+ %3 = load [copy] %2 : $*Klass
689
+ return %3 : $Klass
690
+ }
691
+
692
+ // CHECK-LABEL: sil [ossa] @interior_pointer_lifetime_extension_int_ptr_no_lifetime_ext_needed : $@convention(thin) (@owned Klass) -> @owned Klass {
693
+ // CHECK-NOT: address_to_pointer
694
+ // CHECK-NOT: pointer_to_address
695
+ // CHECK: } // end sil function 'interior_pointer_lifetime_extension_int_ptr_no_lifetime_ext_needed'
696
+ sil [ossa] @interior_pointer_lifetime_extension_int_ptr_no_lifetime_ext_needed : $@convention(thin) (@owned Klass) -> @owned Klass {
697
+ bb0(%0 : @owned $Klass):
698
+ %0a = begin_borrow %0 : $Klass
699
+ %0b = ref_element_addr %0a : $Klass, #Klass.field
700
+ %1 = address_to_pointer %0b : $*Klass to $Builtin.RawPointer
701
+ %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Klass
702
+ %3 = load [copy] %2 : $*Klass
703
+ end_borrow %0a : $Klass
704
+ destroy_value %0 : $Klass
705
+ return %3 : $Klass
706
+ }
707
+
708
+ // In this case, we need to perform the interior pointer lifetime extension.
709
+ //
710
+ // CHECK-LABEL: sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext : $@convention(thin) (@owned Klass) -> @owned Klass {
711
+ // CHECK-NOT: address_to_pointer
712
+ // CHECK-NOT: pointer_to_address
713
+ // CHECK: } // end sil function 'interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext'
714
+ sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext : $@convention(thin) (@owned Klass) -> @owned Klass {
715
+ bb0(%0 : @owned $Klass):
716
+ %0a = begin_borrow %0 : $Klass
717
+ %0b = ref_element_addr %0a : $Klass, #Klass.field
718
+ %1 = address_to_pointer %0b : $*Klass to $Builtin.RawPointer
719
+ %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Klass
720
+ end_borrow %0a : $Klass
721
+ %3 = load [copy] %2 : $*Klass
722
+ destroy_value %0 : $Klass
723
+ return %3 : $Klass
724
+ }
725
+
726
+ // CHECK-LABEL: sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_with_proj : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
727
+ // CHECK-NOT: address_to_pointer
728
+ // CHECK-NOT: pointer_to_address
729
+ // CHECK: } // end sil function 'interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_with_proj'
730
+ sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_with_proj : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
731
+ bb0(%0 : @owned $Klass):
732
+ %0a = begin_borrow %0 : $Klass
733
+ %0b = ref_element_addr %0a : $Klass, #Klass.structField
734
+ %0c = struct_element_addr %0b : $*NativeObjectWrapper, #NativeObjectWrapper.obj
735
+ %1 = address_to_pointer %0c : $*Builtin.NativeObject to $Builtin.RawPointer
736
+ %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Builtin.NativeObject
737
+ end_borrow %0a : $Klass
738
+ %3 = load [copy] %2 : $*Builtin.NativeObject
739
+ destroy_value %0 : $Klass
740
+ return %3 : $Builtin.NativeObject
741
+ }
742
+
743
+ // Make sure we inserted everything in the right places rather than using the
744
+ // ownership verifier.
745
+ //
746
+ // CHECK-LABEL: sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_with_proj_2 : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
747
+ // CHECK: bb0([[ARG:%.*]] : @owned
748
+ // CHECK-NEXT: [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
749
+ // CHECK-NEXT: [[NEW_INT_PTR:%.*]] = ref_element_addr [[BORROWED_ARG]]
750
+ // CHECK-NEXT: br bb1
751
+ //
752
+ // CHECK: bb1:
753
+ // CHECK-NEXT: br bb2
754
+ //
755
+ // CHECK: bb2:
756
+ // CHECK-NEXT: [[NEW_GEP:%.*]] = struct_element_addr [[NEW_INT_PTR]]
757
+ // CHECK-NEXT: br bb3
758
+ //
759
+ // CHECK: bb3:
760
+ // CHECK-NEXT: br bb4
761
+ //
762
+ // CHECK: bb4:
763
+ // CHECK-NEXT: [[RESULT:%.*]] = load [copy] [[NEW_GEP]] :
764
+ // CHECK-NEXT: end_borrow [[BORROWED_ARG]]
765
+ // CHECK-NEXT: destroy_value [[ARG]]
766
+ // CHECK-NEXT: return [[RESULT]]
767
+ // CHECK-NEXT: } // end sil function 'interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_with_proj_2'
768
+ sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_with_proj_2 : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
769
+ bb0(%0 : @owned $Klass):
770
+ %0a = begin_borrow %0 : $Klass
771
+ br bb1
772
+
773
+ bb1:
774
+ %0b = ref_element_addr %0a : $Klass, #Klass.structField
775
+ %0c = struct_element_addr %0b : $*NativeObjectWrapper, #NativeObjectWrapper.obj
776
+ br bb2
777
+
778
+ bb2:
779
+ %1 = address_to_pointer %0c : $*Builtin.NativeObject to $Builtin.RawPointer
780
+ %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Builtin.NativeObject
781
+ br bb3
782
+
783
+ bb3:
784
+ end_borrow %0a : $Klass
785
+ br bb4
786
+
787
+ bb4:
788
+ %3 = load [copy] %2 : $*Builtin.NativeObject
789
+ destroy_value %0 : $Klass
790
+ return %3 : $Builtin.NativeObject
791
+ }
792
+
793
+ // Make sure we inserted everything in the right places rather than using the
794
+ // ownership verifier given we can't eliminate the underlying RAUW.
795
+ //
796
+ // CHECK-LABEL: sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_with_proj_3 : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
797
+ // CHECK: bb0([[ARG:%.*]] : @owned
798
+ // CHECK-NEXT: [[ORIGINAL_BORROW:%.*]] = begin_borrow [[ARG]]
799
+ // CHECK-NEXT: [[COPIED_ARG:%.*]] = copy_value [[ORIGINAL_BORROW]]
800
+ // CHECK-NEXT: [[BORROWED_COPIED_ARG:%.*]] = begin_borrow [[COPIED_ARG]]
801
+ // CHECK-NEXT: [[NEW_INT_PTR:%.*]] = ref_element_addr [[BORROWED_COPIED_ARG]]
802
+ // CHECK-NEXT: br bb1
803
+ //
804
+ // CHECK: bb1:
805
+ // CHECK-NEXT: [[OLD_INT_PTR:%.*]] = ref_element_addr
806
+ // CHECK-NEXT: [[OLD_GEP:%.*]] = struct_element_addr [[OLD_INT_PTR]]
807
+ // CHECK-NEXT: br bb2
808
+ //
809
+ // CHECK: bb2:
810
+ // CHECK-NEXT: // function_ref
811
+ // CHECK-NEXT: [[USER:%.*]] = function_ref @
812
+ // CHECK-NEXT: apply [[USER]]([[OLD_GEP]])
813
+ // CHECK-NEXT: [[NEW_GEP:%.*]] = struct_element_addr [[NEW_INT_PTR]]
814
+ // CHECK-NEXT: br bb3
815
+ //
816
+ // CHECK: bb3:
817
+ // CHECK-NEXT: end_borrow [[ORIGINAL_BORROW]]
818
+ // CHECK-NEXT: br bb4
819
+ //
820
+ // CHECK: bb4:
821
+ // CHECK-NEXT: [[RESULT:%.*]] = load [copy] [[NEW_GEP]]
822
+ // CHECK-NEXT: end_borrow [[BORROWED_COPIED_ARG]]
823
+ // CHECK-NEXT: destroy_value [[COPIED_ARG]]
824
+ // CHECK-NEXT: destroy_value [[ARG]]
825
+ // CHECK-NEXT: return [[RESULT]]
826
+ // CHECK-NEXT: } // end sil function 'interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_with_proj_3'
827
+ sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_with_proj_3 : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
828
+ bb0(%0 : @owned $Klass):
829
+ %0a = begin_borrow %0 : $Klass
830
+ br bb1
831
+
832
+ bb1:
833
+ %0b = ref_element_addr %0a : $Klass, #Klass.structField
834
+ %0c = struct_element_addr %0b : $*NativeObjectWrapper, #NativeObjectWrapper.obj
835
+ br bb2
836
+
837
+ bb2:
838
+ %f = function_ref @inguaranteed_nativeobject_user : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
839
+ apply %f(%0c) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
840
+ %1 = address_to_pointer %0c : $*Builtin.NativeObject to $Builtin.RawPointer
841
+ %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Builtin.NativeObject
842
+ br bb3
843
+
844
+ bb3:
845
+ end_borrow %0a : $Klass
846
+ br bb4
847
+
848
+ bb4:
849
+ %3 = load [copy] %2 : $*Builtin.NativeObject
850
+ destroy_value %0 : $Klass
851
+ return %3 : $Builtin.NativeObject
852
+ }
853
+
854
+ // CHECK-LABEL: sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_loop_1 : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
855
+ // CHECK-NOT: address_to_pointer
856
+ // CHECK-NOT: pointer_to_address
857
+ // CHECK: } // end sil function 'interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_loop_1'
858
+ sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_loop_1 : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
859
+ bb0(%0 : @owned $Klass):
860
+ %0a = begin_borrow %0 : $Klass
861
+ br bb1
862
+
863
+ bb1:
864
+ %0b = ref_element_addr %0a : $Klass, #Klass.structField
865
+ %0c = struct_element_addr %0b : $*NativeObjectWrapper, #NativeObjectWrapper.obj
866
+ br bb2
867
+
868
+ bb2:
869
+ br bbLoop
870
+
871
+ bbLoop:
872
+ %f = function_ref @inguaranteed_nativeobject_user : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
873
+ apply %f(%0c) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
874
+ %1 = address_to_pointer %0c : $*Builtin.NativeObject to $Builtin.RawPointer
875
+ %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Builtin.NativeObject
876
+ cond_br undef, bbBackEdge, bb3
877
+
878
+ bbBackEdge:
879
+ br bbLoop
880
+
881
+ bb3:
882
+ end_borrow %0a : $Klass
883
+ br bb4
884
+
885
+ bb4:
886
+ %3 = load [copy] %2 : $*Builtin.NativeObject
887
+ destroy_value %0 : $Klass
888
+ return %3 : $Builtin.NativeObject
889
+ }
890
+
891
+ // CHECK-LABEL: sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_loop_2 : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
892
+ // CHECK-NOT: address_to_pointer
893
+ // CHECK-NOT: pointer_to_address
894
+ // CHECK: } // end sil function 'interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_loop_2'
895
+ sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_loop_2 : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
896
+ bb0(%0 : @owned $Klass):
897
+ %0a = begin_borrow %0 : $Klass
898
+ br bb1
899
+
900
+ bb1:
901
+ %0b = ref_element_addr %0a : $Klass, #Klass.structField
902
+ %0c = struct_element_addr %0b : $*NativeObjectWrapper, #NativeObjectWrapper.obj
903
+ br bb2
904
+
905
+ bb2:
906
+ br bbLoop
907
+
908
+ bbLoop:
909
+ %f = function_ref @inguaranteed_nativeobject_user : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
910
+ apply %f(%0c) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
911
+ %1 = address_to_pointer %0c : $*Builtin.NativeObject to $Builtin.RawPointer
912
+ %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Builtin.NativeObject
913
+ br bbLoop2
914
+
915
+ bbLoop2:
916
+ %3 = load [copy] %2 : $*Builtin.NativeObject
917
+ cond_br undef, bbBackEdge, bb3
918
+
919
+ bbBackEdge:
920
+ destroy_value %3 : $Builtin.NativeObject
921
+ br bbLoop
922
+
923
+ bb3:
924
+ end_borrow %0a : $Klass
925
+ br bb4
926
+
927
+ bb4:
928
+ destroy_value %0 : $Klass
929
+ return %3 : $Builtin.NativeObject
930
+ }
931
+
932
+ // CHECK-LABEL: sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_loop_3 : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
933
+ // CHECK-NOT: address_to_pointer
934
+ // CHECK-NOT: pointer_to_address
935
+ // CHECK: } // end sil function 'interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_loop_3'
936
+ sil [ossa] @interior_pointer_lifetime_extension_int_ptr_need_lifetime_ext_loop_3 : $@convention(thin) (@owned Klass) -> @owned Builtin.NativeObject {
937
+ bb0(%0 : @owned $Klass):
938
+ %0a = begin_borrow %0 : $Klass
939
+ br bb1
940
+
941
+ bb1:
942
+ br bb2
943
+
944
+ bb2:
945
+ br bbLoop(%0a : $Klass, undef : $Klass)
946
+
947
+ bbLoop(%arg : @guaranteed $Klass, %base : @owned $Klass):
948
+ %0b = ref_element_addr %arg : $Klass, #Klass.structField
949
+ %0c = struct_element_addr %0b : $*NativeObjectWrapper, #NativeObjectWrapper.obj
950
+ br bbLoop2
951
+
952
+ bbLoop2:
953
+ %f = function_ref @inguaranteed_nativeobject_user : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
954
+ apply %f(%0c) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
955
+ %1 = address_to_pointer %0c : $*Builtin.NativeObject to $Builtin.RawPointer
956
+ %2 = pointer_to_address %1 : $Builtin.RawPointer to [strict] $*Builtin.NativeObject
957
+ br bbLoop3
958
+
959
+ bbLoop3:
960
+ end_borrow %arg : $Klass
961
+ destroy_value %base : $Klass
962
+ %3 = load [copy] %2 : $*Builtin.NativeObject
963
+ cond_br undef, bbBackEdge, bb3
964
+
965
+ bbBackEdge:
966
+ destroy_value %3 : $Builtin.NativeObject
967
+ br bbLoop(undef : $Klass, undef : $Klass)
968
+
969
+ bb3:
970
+ br bb4
971
+
972
+ bb4:
973
+ destroy_value %0 : $Klass
974
+ return %3 : $Builtin.NativeObject
975
+ }
0 commit comments