@@ -21,19 +21,23 @@ sil @owned_user : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2121sil @get_owned_obj : $@convention(thin) () -> @owned Builtin.NativeObject
2222sil @unreachable_guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> MyNever
2323sil @inout_user : $@convention(thin) (@inout FakeOptional<NativeObjectPair>) -> ()
24+ sil @get_native_object : $@convention(thin) () -> @owned Builtin.NativeObject
2425
2526struct NativeObjectPair {
2627 var obj1 : Builtin.NativeObject
2728 var obj2 : Builtin.NativeObject
2829}
2930
31+ sil @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
32+
3033struct FakeOptionalNativeObjectPairPair {
3134 var pair1 : FakeOptional<NativeObjectPair>
3235 var pair2 : FakeOptional<NativeObjectPair>
3336}
3437sil @inout_user2 : $@convention(thin) (@inout FakeOptionalNativeObjectPairPair) -> ()
3538
3639sil @get_nativeobject_pair : $@convention(thin) () -> @owned NativeObjectPair
40+ sil @consume_nativeobject_pair : $@convention(thin) (@owned NativeObjectPair) -> ()
3741
3842protocol MyFakeAnyObject : Klass {
3943 func myFakeMethod()
@@ -2868,3 +2872,208 @@ bb3(%result : @owned $FakeOptional<Builtin.NativeObject>):
28682872 dealloc_stack %allocStack : $*Builtin.NativeObject
28692873 return %result : $FakeOptional<Builtin.NativeObject>
28702874}
2875+
2876+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case : $@convention(thin) () -> () {
2877+ // CHECK-NOT: copy_value
2878+ // CHECK: } // end sil function 'simple_recursive_copy_case'
2879+ sil [ossa] @simple_recursive_copy_case : $@convention(thin) () -> () {
2880+ bb0:
2881+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
2882+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
2883+ %1 = copy_value %pair : $NativeObjectPair
2884+ %2 = begin_borrow %1 : $NativeObjectPair
2885+ %3 = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
2886+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2887+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2888+ end_borrow %2 : $NativeObjectPair
2889+ destroy_value %1 : $NativeObjectPair
2890+ destroy_value %pair : $NativeObjectPair
2891+ %9999 = tuple()
2892+ return %9999 : $()
2893+ }
2894+
2895+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_2 : $@convention(thin) () -> () {
2896+ // CHECK-NOT: copy_value
2897+ // CHECK: } // end sil function 'simple_recursive_copy_case_2'
2898+ sil [ossa] @simple_recursive_copy_case_2 : $@convention(thin) () -> () {
2899+ bb0:
2900+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
2901+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
2902+ %1 = copy_value %pair : $NativeObjectPair
2903+ %2 = begin_borrow %1 : $NativeObjectPair
2904+ destroy_value %pair : $NativeObjectPair
2905+ %3 = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
2906+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2907+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2908+ end_borrow %2 : $NativeObjectPair
2909+ destroy_value %1 : $NativeObjectPair
2910+ %9999 = tuple()
2911+ return %9999 : $()
2912+ }
2913+
2914+ // We fail in this case since the lifetime of %pair ends too early and our
2915+ // joined lifetime analysis is too simplistic to handle this case.
2916+ //
2917+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_3 : $@convention(thin) () -> () {
2918+ // CHECK: copy_value
2919+ // CHECK: } // end sil function 'simple_recursive_copy_case_3'
2920+ sil [ossa] @simple_recursive_copy_case_3 : $@convention(thin) () -> () {
2921+ bb0:
2922+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
2923+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
2924+ %1 = copy_value %pair : $NativeObjectPair
2925+ %2 = begin_borrow %1 : $NativeObjectPair
2926+ %3 = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
2927+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2928+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2929+ end_borrow %2 : $NativeObjectPair
2930+ %consumeFunc = function_ref @consume_nativeobject_pair : $@convention(thin) (@owned NativeObjectPair) -> ()
2931+ apply %consumeFunc(%pair) : $@convention(thin) (@owned NativeObjectPair) -> ()
2932+ cond_br undef, bb1, bb2
2933+
2934+ bb1:
2935+ (%1a, %1b) = destructure_struct %1 : $NativeObjectPair
2936+ %ownedUser = function_ref @owned_user : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2937+ apply %ownedUser(%1a) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2938+ apply %ownedUser(%1b) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2939+ br bb3
2940+
2941+ bb2:
2942+ destroy_value %1 : $NativeObjectPair
2943+ br bb3
2944+
2945+ bb3:
2946+ %9999 = tuple()
2947+ return %9999 : $()
2948+ }
2949+
2950+ // This case fails due to the destructure of our parent object even though the
2951+ // lifetimes line up. We don't support destructures here yet.
2952+ //
2953+ // TODO: Handle this!
2954+ //
2955+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_4 : $@convention(thin) () -> () {
2956+ // CHECK: copy_value
2957+ // CHECK: } // end sil function 'simple_recursive_copy_case_4'
2958+ sil [ossa] @simple_recursive_copy_case_4 : $@convention(thin) () -> () {
2959+ bb0:
2960+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
2961+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
2962+ %1 = copy_value %pair : $NativeObjectPair
2963+ %2 = begin_borrow %1 : $NativeObjectPair
2964+ %3 = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
2965+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2966+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2967+ end_borrow %2 : $NativeObjectPair
2968+ %consumeFunc = function_ref @consume_nativeobject_pair : $@convention(thin) (@owned NativeObjectPair) -> ()
2969+ destroy_value %1 : $NativeObjectPair
2970+ (%pair1, %pair2) = destructure_struct %pair : $NativeObjectPair
2971+ %ownedUser = function_ref @owned_user : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2972+ apply %ownedUser(%pair1) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2973+ apply %ownedUser(%pair2) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2974+ %9999 = tuple()
2975+ return %9999 : $()
2976+ }
2977+
2978+ // This case fails due to the destructure of our parent object even though the
2979+ // lifetimes line up. We don't support destructures here yet.
2980+ //
2981+ // TODO: Handle this!
2982+ //
2983+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_5 : $@convention(thin) () -> () {
2984+ // CHECK: copy_value
2985+ // CHECK: } // end sil function 'simple_recursive_copy_case_5'
2986+ sil [ossa] @simple_recursive_copy_case_5 : $@convention(thin) () -> () {
2987+ bb0:
2988+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
2989+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
2990+ %1 = copy_value %pair : $NativeObjectPair
2991+ %2 = begin_borrow %1 : $NativeObjectPair
2992+ %3 = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
2993+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2994+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
2995+ end_borrow %2 : $NativeObjectPair
2996+ %consumeFunc = function_ref @consume_nativeobject_pair : $@convention(thin) (@owned NativeObjectPair) -> ()
2997+ (%pair1, %pair2) = destructure_struct %pair : $NativeObjectPair
2998+ %ownedUser = function_ref @owned_user : $@convention(thin) (@owned Builtin.NativeObject) -> ()
2999+ destroy_value %1 : $NativeObjectPair
3000+ apply %ownedUser(%pair1) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
3001+ apply %ownedUser(%pair2) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
3002+ %9999 = tuple()
3003+ return %9999 : $()
3004+ }
3005+
3006+ // Make sure we do not eliminate copies where only the destroy_value is outside
3007+ // of the lifetime of the parent value, but a begin_borrow extends the lifetime
3008+ // of the value.
3009+ //
3010+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_destroying_use_out_of_lifetime : $@convention(thin) () -> () {
3011+ // CHECK: copy_value
3012+ // CHECK: } // end sil function 'simple_recursive_copy_case_destroying_use_out_of_lifetime'
3013+ sil [ossa] @simple_recursive_copy_case_destroying_use_out_of_lifetime : $@convention(thin) () -> () {
3014+ bb0:
3015+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
3016+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
3017+ %pairBorrow = begin_borrow %pair : $NativeObjectPair
3018+ %3 = struct_extract %pairBorrow : $NativeObjectPair, #NativeObjectPair.obj1
3019+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3020+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3021+ end_borrow %pairBorrow : $NativeObjectPair
3022+ cond_br undef, bb1, bb2
3023+
3024+ bb1:
3025+ %1 = copy_value %pair : $NativeObjectPair
3026+ %2 = begin_borrow %1 : $NativeObjectPair
3027+ destroy_value %pair : $NativeObjectPair
3028+ %3a = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
3029+ apply %gUserFun(%3a) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3030+ end_borrow %2 : $NativeObjectPair
3031+ destroy_value %1 : $NativeObjectPair
3032+ br bb3
3033+
3034+ bb2:
3035+ destroy_value %pair : $NativeObjectPair
3036+ br bb3
3037+
3038+ bb3:
3039+ %9999 = tuple()
3040+ return %9999 : $()
3041+ }
3042+
3043+ // Second version of the test that consumes the pair in case we make the
3044+ // lifetime joining smart enough to handle the original case.
3045+ //
3046+ // CHECK-LABEL: sil [ossa] @simple_recursive_copy_case_destroying_use_out_of_lifetime_2 : $@convention(thin) () -> () {
3047+ // CHECK: copy_value
3048+ // CHECK: } // end sil function 'simple_recursive_copy_case_destroying_use_out_of_lifetime_2'
3049+ sil [ossa] @simple_recursive_copy_case_destroying_use_out_of_lifetime_2 : $@convention(thin) () -> () {
3050+ bb0:
3051+ %f = function_ref @get_object_pair : $@convention(thin) () -> @owned NativeObjectPair
3052+ %pair = apply %f() : $@convention(thin) () -> @owned NativeObjectPair
3053+ %pairBorrow = begin_borrow %pair : $NativeObjectPair
3054+ %3 = struct_extract %pairBorrow : $NativeObjectPair, #NativeObjectPair.obj1
3055+ %gUserFun = function_ref @guaranteed_user : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3056+ apply %gUserFun(%3) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3057+ end_borrow %pairBorrow : $NativeObjectPair
3058+ cond_br undef, bb1, bb2
3059+
3060+ bb1:
3061+ %1 = copy_value %pair : $NativeObjectPair
3062+ %2 = begin_borrow %1 : $NativeObjectPair
3063+ destroy_value %pair : $NativeObjectPair
3064+ %3a = struct_extract %2 : $NativeObjectPair, #NativeObjectPair.obj1
3065+ apply %gUserFun(%3a) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> ()
3066+ end_borrow %2 : $NativeObjectPair
3067+ destroy_value %1 : $NativeObjectPair
3068+ br bb3
3069+
3070+ bb2:
3071+ %consumePair = function_ref @consume_nativeobject_pair : $@convention(thin) (@owned NativeObjectPair) -> ()
3072+ apply %consumePair(%pair) : $@convention(thin) (@owned NativeObjectPair) -> ()
3073+ br bb3
3074+
3075+ bb3:
3076+ %9999 = tuple()
3077+ return %9999 : $()
3078+ }
3079+
0 commit comments