// RUN: %target-sil-opt -sil-print-types -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts -enable-experimental-feature Lifetimes %s | %FileCheck %s // RUN: %target-sil-opt -sil-print-types -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts -enable-experimental-feature Lifetimes %s | %FileCheck -check-prefix=CHECK-NEGATIVE %s // REQUIRES: swift_in_compiler // REQUIRES: swift_feature_Lifetimes import Builtin import Swift ///////////////////// // Data Structures // ///////////////////// class foo { var a: Int deinit init() } class bar { var start: foo var end: foo deinit init() } struct baz { var start: foo var end: foo init() } struct boo { var tbaz = baz() var a = 0 init() } struct lotsoffield { var tbaz = baz() var a = 0 var b = 0 var c = 0 var d = 0 init() } struct goo { var left : foo var right : foo var top : foo var bottom : foo } public protocol P { func foo() -> Int64 } public protocol KlassFoo : class { func bar() -> Int64 } public class KlassBar : KlassFoo { public func bar() -> Int64 deinit init() } indirect public enum IndirectEnum : Hashable { case A case B(IndirectEnum) } struct ValueGenericType {} sil @use_Int : $@convention(thin) (Int) -> () sil @use_Int64 : $@convention(thin) (Int64) -> () sil @use_Generic : $@convention(thin) (@in_guaranteed T) -> () sil_global public @sil_global1 : $Builtin.Int32 sil @update_global: $@convention(thin) () -> () { bb0: %sil_global1_addr = global_addr @sil_global1 : $*Builtin.Int32 %1 = integer_literal $Builtin.Int32, 1 store %1 to %sil_global1_addr : $*Builtin.Int32 %4 = tuple () return %4 : $() } // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @argument_with_incomplete_epilogue_release // CHECK: [[IN2:%.*]] = struct_extract [[IN1:%.*]] : $goo, #goo.top // CHECK: function_ref @$s41argument_with_incomplete_epilogue_releaseTf4x_nTf4gn_n : $@convention(thin) (@guaranteed foo, @owned foo) -> () // CHECK: release_value [[IN2]] sil @argument_with_incomplete_epilogue_release : $@convention(thin) (@owned goo) -> () { bb0(%0 : $goo): // make inline costs = 2 %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %1 = struct_extract %0 : $goo, #goo.top %2 = ref_element_addr %1 : $foo, #foo.a %3 = load %2 : $*Int %4 = function_ref @use_Int : $@convention(thin) (Int) -> () apply %4(%3) : $@convention(thin) (Int) -> () %5 = struct_extract %0 : $goo, #goo.bottom %6 = ref_element_addr %5 : $foo, #foo.a %7 = load %6 : $*Int apply %4(%7) : $@convention(thin) (Int) -> () release_value %1 : $foo %8 = tuple () return %8 : $() } // We do this check separately to ensure that this does not occur anywhere in // the output for the file. (Maybe this is an interesting enough feature to add to FileCheck?). // CHECK-NEGATIVE-NOT: sil [serialized] @_TTSfq4d_n__dead_arg_no_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { // CHECK-NEGATIVE-NOT: sil [serialized] @_TTSfq4g__owned_to_guaranteed_multibb_callee_with_release_not_in_exit : $@convention(thin) (@owned Builtin.NativeObject) -> () { sil [serialized] @user : $@convention(thin) (Builtin.NativeObject) -> () sil [serialized] @create_object : $@convention(thin) () -> Builtin.NativeObject // Make sure argument is exploded and the baz part is not passed in as argument, as its only use // is a release. // // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @dead_argument_due_to_only_release_user // CHECK: [[IN:%.*]] = function_ref @$s38dead_argument_due_to_only_release_userTf4gX_n // CHECK: [[IN2:%.*]] = struct_extract [[IN1:%.*]] : $boo, #boo.a // CHECK: apply [[IN]]([[IN2]]) sil @dead_argument_due_to_only_release_user : $@convention(thin) (@owned boo) -> (Int, Int) { bb0(%0 : $boo): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %1 = struct_extract %0 : $boo, #boo.tbaz %2 = struct_extract %0 : $boo, #boo.a release_value %1 : $baz %4 = tuple (%2 : $Int, %2 : $Int) return %4 : $(Int, Int) } // Make sure argument is exploded and the baz part is not passed in as argument, as its only use // is a release. // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @dead_argument_due_to_only_release_user_but__exploded // CHECK: [[FN1:%.*]] = function_ref @$s52dead_argument_due_to_only_release_user_but__explodedTf4gX_n // CHECK: [[IN1:%.*]] = struct_extract %0 : $lotsoffield, #lotsoffield.c // CHECK: [[IN2:%.*]] = struct_extract %0 : $lotsoffield, #lotsoffield.b // CHECK: [[IN3:%.*]] = struct_extract %0 : $lotsoffield, #lotsoffield.a // CHECK: apply [[FN1]]([[IN3]], [[IN2]], [[IN1]]) // CHECK-LABEL: } // end sil function 'dead_argument_due_to_only_release_user_but__exploded' sil @dead_argument_due_to_only_release_user_but__exploded : $@convention(thin) (@owned lotsoffield) -> (Int, Int, Int) { bb0(%0 : $lotsoffield): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %1 = struct_extract %0 : $lotsoffield, #lotsoffield.tbaz %2 = struct_extract %0 : $lotsoffield, #lotsoffield.a %3 = struct_extract %0 : $lotsoffield, #lotsoffield.b %4 = struct_extract %0 : $lotsoffield, #lotsoffield.c release_value %1 : $baz %5 = tuple (%2 : $Int, %3 : $Int, %4 : $Int) return %5 : $(Int, Int, Int) } // Since this is a value that contains only a singular owned type, there is no // point from an ARC perspective in splitting it up. We still want to perform // owned to guaranteed though. // // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @dead_argument_due_to_more_than_release_user // CHECK: bb{{[0-9]+}}([[BOO:%.*]] : $boo): // CHECK: [[FUNCTION:%.*]] = function_ref @$s43dead_argument_due_to_more_than_release_userTf4g_n : $@convention(thin) (@guaranteed boo) -> (Int, Int) // CHECK: [[RESULT:%.*]] = apply [[FUNCTION]]([[BOO]]) // CHECK: return [[RESULT]] // CHECK-LABEL: } // end sil function 'dead_argument_due_to_more_than_release_user' sil @dead_argument_due_to_more_than_release_user : $@convention(thin) (@owned boo) -> (Int, Int) { bb0(%0 : $boo): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %1 = struct_extract %0 : $boo, #boo.tbaz %2 = struct_extract %0 : $boo, #boo.a retain_value %1 : $baz release_value %1 : $baz %4 = tuple (%2 : $Int, %2 : $Int) return %4 : $(Int, Int) } // CHECK-LABEL: sil [serialized] @dead_arg_no_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { // CHECK-NOT: function_ref @_TTSf4d_n__dead_arg_no_callsites sil [serialized] @dead_arg_no_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 cond_br undef, bb1, bb2 bb1: br bb3 bb2: br bb3 bb3: %2 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () %3 = apply %2(%1) : $@convention(thin) (Builtin.NativeObject) -> () %4 = tuple() return %4 : $() } // Make sure %0 is a dead argument. // // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @exploded_release_to_dead_argument // CHECK: bb0([[INPUT_ARG0:%[0-9]+]] : $boo): // CHECK: [[IN1:%.*]] = function_ref @$s33exploded_release_to_dead_argumentTf4d_n // CHECK: apply [[IN1]]() // CHECK: release_value [[INPUT_ARG0]] sil @exploded_release_to_dead_argument : $@convention(thin) (@owned boo) -> () { bb0(%0 : $boo): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %1 = struct_extract %0 : $boo, #boo.tbaz %2 = struct_extract %1 : $baz, #baz.start %3 = struct_extract %1 : $baz, #baz.end release_value %2 : $foo release_value %3 : $foo %f = function_ref @update_global: $@convention(thin) () -> () apply %f() : $@convention(thin) () -> () %4 = tuple () return %4 : $() } // Make sure %0 is not a dead argument, but gets converted to a guaranteed arg. // // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @exploded_release_to_guaranteed_param // CHECK: bb0([[INPUT_ARG0:%[0-9]+]] : $boo): // CHECK: [[IN1:%.*]] = function_ref @$s36exploded_release_to_guaranteed_paramTf4gX_n // CHECK: release_value [[INPUT_ARG0]] sil @exploded_release_to_guaranteed_param : $@convention(thin) (@owned boo) -> () { bb0(%0 : $boo): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %1 = struct_extract %0 : $boo, #boo.tbaz %2 = struct_extract %1 : $baz, #baz.start %3 = struct_extract %1 : $baz, #baz.end %4 = struct_extract %0 : $boo, #boo.a %5 = function_ref @use_Int : $@convention(thin) (Int) -> () apply %5(%4) : $@convention(thin) (Int) -> () release_value %2 : $foo release_value %3 : $foo %6 = tuple () return %6 : $() } // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @single_owned_return_value // CHECK: bb0([[INPUT_ARG0:%[0-9]+]] : $boo): // CHECK: [[IN1:%.*]] = function_ref @$s25single_owned_return_valueTf4n_g // CHECK: [[IN2:%.*]] = apply [[IN1]]([[INPUT_ARG0]] // CHECK: retain_value [[IN2]] sil @single_owned_return_value : $@convention(thin) (@owned boo) -> @owned boo { bb0(%0 : $boo): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 retain_value %0 : $boo return %0 : $boo } // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @single_owned_return_value_with_self_recursion // CHECK: function_ref @$s45single_owned_return_value_with_self_recursionTf4n_g // CHECK: [[RET:%.*]] = apply // CHECK: retain_value [[RET]] sil @single_owned_return_value_with_self_recursion : $@convention(thin) (@owned boo) -> @owned boo { bb0(%0 : $boo): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 cond_br undef, bb1, bb2 bb1: retain_value %0 : $boo br bb3(%0 : $boo) bb2: %2 = function_ref @single_owned_return_value_with_self_recursion : $@convention(thin) (@owned boo) -> @owned boo %3 = apply %2(%0) : $@convention(thin) (@owned boo) -> @owned boo br bb3 (%3 : $boo) bb3(%4 : $boo): return %4 : $boo } // The function is public (hence possibly used externally) and the full boo // argument is live. Consequently, it is not specialized. // CHECK-LABEL: sil @single_owned_return_value_with_interfering_release // CHECK: bb0([[INPUT_ARG0:%[0-9]+]] : $boo): // CHECK: return // CHECK-LABEL: } // end sil function 'single_owned_return_value_with_interfering_release' sil @single_owned_return_value_with_interfering_release : $@convention(thin) (@owned boo) -> boo { bb0(%0 : $boo): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 retain_value %0 : $boo %1 = struct_extract %0 : $boo, #boo.tbaz %2 = struct_extract %1 : $baz, #baz.start release_value %2: $foo return %0 : $boo } // CHECK-LABEL: sil @no_fso_recursive_result_is_not_returned : // CHECK-NOT: release_value // CHECK: bb2: // CHECK-NEXT: retain_value %0 // CHECK: return // CHECK-LABEL: } // end sil function 'no_fso_recursive_result_is_not_returned' sil @no_fso_recursive_result_is_not_returned : $@convention(method) (@guaranteed IndirectEnum, @guaranteed IndirectEnum) -> @owned IndirectEnum { bb0(%0 : $IndirectEnum, %1 : $IndirectEnum): switch_enum %1 : $IndirectEnum, case #IndirectEnum.B!enumelt: bb1, default bb2 bb1(%3 : ${ var IndirectEnum }): %4 = project_box %3 : ${ var IndirectEnum }, 0 %5 = load %4 : $*IndirectEnum %6 = function_ref @no_fso_recursive_result_is_not_returned : $@convention(method) (@guaranteed IndirectEnum, @guaranteed IndirectEnum) -> @owned IndirectEnum // The result of the self-recursion is not returned (but put in a box). // This prevents guaranteed -> owned return value specialization. %7 = apply %6(%0, %5) : $@convention(method) (@guaranteed IndirectEnum, @guaranteed IndirectEnum) -> @owned IndirectEnum %8 = alloc_box ${ var IndirectEnum } %9 = project_box %8 : ${ var IndirectEnum }, 0 store %7 to %9 : $*IndirectEnum %11 = enum $IndirectEnum, #IndirectEnum.B!enumelt, %8 : ${ var IndirectEnum } br bb3(%11 : $IndirectEnum) bb2: retain_value %0 : $IndirectEnum br bb3(%0 : $IndirectEnum) bb3(%35 : $IndirectEnum): return %35 : $IndirectEnum } // Make sure we do not move the retain_value in the throw block. // // CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @owned_to_unowned_retval_with_error_result : $@convention(thin) (@owned boo) -> (@owned boo, @error any Error) { // CHECK: function_ref @$s41owned_to_unowned_retval_with_error_resultTfq4n_g : $@convention(thin) (@owned boo) -> (boo, @error any Error) // CHECK: bb1 // CHECK-NOT: retain_value // CHECK: bb2 sil [serialized] @owned_to_unowned_retval_with_error_result : $@convention(thin) (@owned boo) -> (@owned boo, @error Error) { bb0(%0 : $boo): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 cond_br undef, bb1, bb2 bb1: retain_value %0 : $boo return %0 : $boo bb2: retain_value %0 : $boo throw undef : $Error } // CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { // CHECK: bb0 // CHECK-NEXT: function_ref // CHECK-NEXT: function_ref @$s23dead_arg_with_callsitesTfq4dn_n : $@convention(thin) (Builtin.NativeObject) -> () // CHECK-NEXT: apply // CHECK-NEXT: return sil [serialized] @dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 debug_value %0 : $Builtin.NativeObject // debug_value of a dead arg should also be deleted. cond_br undef, bb1, bb2 bb1: br bb3 bb2: br bb3 bb3: %2 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () %3 = apply %2(%1) : $@convention(thin) (Builtin.NativeObject) -> () %4 = tuple() return %4 : $() } // CHECK-NOT: sil hidden @private_dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { sil private @private_dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 cond_br undef, bb1, bb2 bb1: br bb3 bb2: br bb3 bb3: %2 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () %3 = apply %2(%1) : $@convention(thin) (Builtin.NativeObject) -> () %4 = tuple() return %4 : $() } // CHECK-LABEL: sil @dead_arg_callsite_1 : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { // CHECK: bb0 // CHECK: [[OPT_FUN:%[0-9]+]] = function_ref @$s23dead_arg_with_callsitesTfq4dn_n : $@convention(thin) (Builtin.NativeObject) -> () // CHECK-NEXT: apply [[OPT_FUN]]( // CHECK: [[PRIV_OPT_FUN:%[0-9]+]] = function_ref @$s31private_dead_arg_with_callsitesTf4dn_n : $@convention(thin) (Builtin.NativeObject) -> () // CHECK-NEXT: apply [[PRIV_OPT_FUN]] sil @dead_arg_callsite_1 : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): %2 = function_ref @dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () %3 = apply %2(%0, %1) : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () %4 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () // This ensures that %0 is not dead in this function. We don't want to specialize this. apply %4(%0) : $@convention(thin) (Builtin.NativeObject) -> () %5 = function_ref @private_dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () %6 = apply %5(%0, %1) : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () %7 = tuple() return %7 : $() } // This test makes sure we can look up an already specialized callee instead of regenerating one. // CHECK-LABEL: sil [serialized] @dead_arg_callsite_2 : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { // CHECK: [[OPT_FUN:%[0-9]+]] = function_ref @$s23dead_arg_with_callsitesTfq4dn_n : $@convention(thin) (Builtin.NativeObject) -> () // CHECK-NEXT: apply [[OPT_FUN]]( sil [serialized] @dead_arg_callsite_2 : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): %2 = function_ref @dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () %3 = apply %2(%0, %1) : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () %4 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () // This ensures that %0 is not dead in this function. We don't want to specialize this. apply %4(%0) : $@convention(thin) (Builtin.NativeObject) -> () %5 = tuple() return %5 : $() } // DISABLED for now. Inliner does not look through thin_to_thick_function. // // This test case verifies we can specialize functions called through thin_to_thick_function. // DISABLECHECK-LABEL: sil [serialized] @dead_arg_obfuscated_callsite : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { // DISABLECHECK: [[OPT_FUN:%[0-9]+]] = function_ref @_TTSf4d_n__dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject) -> () // DISABLECHECK-NEXT: apply [[OPT_FUN]]( sil [serialized] @dead_arg_obfuscated_callsite : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): %2 = function_ref @dead_arg_with_callsites : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () %3 = thin_to_thick_function %2 : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () to $@callee_owned (Builtin.NativeObject, Builtin.NativeObject) -> () %4 = apply %3(%0, %1) : $@callee_owned (Builtin.NativeObject, Builtin.NativeObject) -> () %5 = tuple() return %5 : $() } sil [serialized] @exploded_release_to_guaranteed_param_callsite : $@convention(thin) (@owned boo) -> () { bb0(%0 : $boo): %2 = function_ref @exploded_release_to_guaranteed_param : $@convention(thin) (@owned boo) -> () retain_value %0 : $boo %4 = apply %2(%0) : $@convention(thin) (@owned boo) -> () %5 = tuple() return %5 : $() } // Make sure we pull out the retain_value from the callee. // // The retain and release can be got rid of easily by arc this way. // // CHECK-LABEL: sil @single_owned_return_value_with_self_recursion_callsite // CHECK: [[RET:%.*]] = apply // CHECK: retain_value [[RET]] // CHECK: release_value [[RET]] sil @single_owned_return_value_with_self_recursion_callsite : $@convention(thin) (@owned boo) -> () { bb0(%0 : $boo): %2 = function_ref @single_owned_return_value_with_self_recursion : $@convention(thin) (@owned boo) -> @owned boo %4 = apply %2(%0) : $@convention(thin) (@owned boo) -> @owned boo release_value %4 : $boo %5 = tuple() return %5 : $() } sil [serialized] @exploded_release_to_dead_param_callsite : $@convention(thin) (@owned boo) -> () { bb0(%0 : $boo): %2 = function_ref @exploded_release_to_dead_argument : $@convention(thin) (@owned boo) -> () retain_value %0 : $boo %4 = apply %2(%0) : $@convention(thin) (@owned boo) -> () %5 = tuple() return %5 : $() } sil [serialized] @single_owned_return_value_callsite : $@convention(thin) (@owned boo) -> () { bb0(%0 : $boo): cond_br undef, bb1, bb2 bb1: br bb3 bb2: br bb3 bb3: %2 = function_ref @single_owned_return_value : $@convention(thin) (@owned boo) -> @owned boo %3 = apply %2(%0) : $@convention(thin) (@owned boo) -> @owned boo %4 = tuple() return %4 : $() } sil [serialized] @single_owned_return_value_with_interfering_release_callsite : $@convention(thin) (@owned boo) -> () { bb0(%0 : $boo): cond_br undef, bb1, bb2 bb1: br bb3 bb2: br bb3 bb3: %2 = function_ref @single_owned_return_value_with_interfering_release : $@convention(thin) (@owned boo) -> boo %3 = apply %2(%0) : $@convention(thin) (@owned boo) -> boo %4 = tuple() return %4 : $() } sil [serialized] @owned_to_unowned_retval_with_error_result_callsite : $@convention(thin) (@owned boo) -> () { bb0(%0 : $boo): cond_br undef, bb1, bb2 bb1: br bb3 bb2: br bb3 bb3: %2 = function_ref @owned_to_unowned_retval_with_error_result : $@convention(thin) (@owned boo) -> (@owned boo, @error Error) try_apply %2(%0) : $@convention(thin) (@owned boo) -> (@owned boo, @error Error), normal bb4, error bb5 bb4(%99 : $boo): %4 = tuple() return %4 : $() bb5(%100 : $Error): unreachable } sil [serialized] @dead_argument_due_to_only_release_user_callsite : $@convention(thin) (@owned boo) -> () { bb0(%0 : $boo): %2 = function_ref @dead_argument_due_to_only_release_user : $@convention(thin) (@owned boo) -> (Int, Int) %4 = apply %2(%0) : $@convention(thin) (@owned boo) -> (Int, Int) %5 = tuple() return %5 : $() } sil [serialized] @dead_argument_due_to_only_release_user_but__exploded_callsite : $@convention(thin) (@owned lotsoffield) -> () { bb0(%0 : $lotsoffield): %2 = function_ref @dead_argument_due_to_only_release_user_but__exploded : $@convention(thin) (@owned lotsoffield) -> (Int, Int, Int) %4 = apply %2(%0) : $@convention(thin) (@owned lotsoffield) -> (Int, Int, Int) %5 = tuple() return %5 : $() } sil [serialized] @dead_argument_due_to_more_than_release_user_callsite : $@convention(thin) (@owned boo) -> () { bb0(%0 : $boo): %2 = function_ref @dead_argument_due_to_more_than_release_user : $@convention(thin) (@owned boo) -> (Int, Int) %4 = apply %2(%0) : $@convention(thin) (@owned boo) -> (Int, Int) %5 = tuple() return %5 : $() } sil [serialized] @argument_with_incomplete_epilogue_release_callsite : $@convention(thin) (@owned goo) -> () { bb0(%0 : $goo): %2 = function_ref @argument_with_incomplete_epilogue_release : $@convention(thin) (@owned goo) -> () %4 = apply %2(%0) : $@convention(thin) (@owned goo) -> () %5 = tuple() return %5 : $() } //======================================== // @owned => @guaranteed with error result // CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @owned_to_guaranteed_with_error_result : $@convention(thin) (@owned Builtin.NativeObject, Int) -> (Int, @error any Error) { // CHECK: [[FUNC_REF:%[0-9]+]] = function_ref @$s37owned_to_guaranteed_with_error_resultTfq4gn_n : $@convention(thin) (@guaranteed Builtin.NativeObject, Int) // CHECK: try_apply [[FUNC_REF]]({{.*}}, normal bb1, error bb2 // CHECK: bb1([[NORMRET:%[0-9]+]] : $Int): // CHECK-NEXT: release_value // CHECK-NEXT: return [[NORMRET]] // CHECK: bb2([[THROW:%[0-9]+]] : $any Error): // CHECK-NEXT: release_value // CHECK-NEXT: throw [[THROW]] sil [serialized] @owned_to_guaranteed_with_error_result : $@convention(thin) (@owned Builtin.NativeObject, Int) -> (Int, @error Error) { bb0(%0 : $Builtin.NativeObject, %1 : $Int): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %f1 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () apply %f1(%0) : $@convention(thin) (Builtin.NativeObject) -> () cond_br undef, bb1, bb2 bb1: release_value %0 : $Builtin.NativeObject return %1 : $Int bb2: release_value %0 : $Builtin.NativeObject throw undef : $Error } // CHECK-LABEL: sil [serialized] @owned_to_guaranteed_with_error_caller : $@convention(thin) (Builtin.NativeObject, Int) -> (Int, @error any Error) { // CHECK: [[FUNC_REF:%[0-9]+]] = function_ref @$s37owned_to_guaranteed_with_error_resultTfq4gn_n : $@convention(thin) (@guaranteed Builtin.NativeObject, Int) // CHECK: try_apply [[FUNC_REF]]({{.*}}, normal bb1, error bb2 // CHECK: bb1([[NORMRET:%[0-9]+]] : $Int): // CHECK-NEXT: release_value // CHECK: bb2([[THROW:%[0-9]+]] : $any Error): // CHECK-NEXT: release_value sil [serialized] @owned_to_guaranteed_with_error_caller : $@convention(thin) (Builtin.NativeObject, Int) -> (Int, @error Error) { bb0(%0 : $Builtin.NativeObject, %1 : $Int): %f1 = function_ref @owned_to_guaranteed_with_error_result : $@convention(thin) (@owned Builtin.NativeObject, Int) -> (Int, @error Error) try_apply %f1(%0, %1) : $@convention(thin) (@owned Builtin.NativeObject, Int) -> (Int, @error Error), normal bb1, error bb2 bb1(%a1 : $Int): return %a1 : $Int bb2(%a2 : $Error): throw %a2 : $Error } // CHECK-LABEL: sil [serialized] @owned_to_guaranteed_with_nothrow_caller : $@convention(thin) (Builtin.NativeObject, Int) -> Int { // CHECK: [[FUNC_REF:%[0-9]+]] = function_ref @$s37owned_to_guaranteed_with_error_resultTfq4gn_n : $@convention(thin) (@guaranteed Builtin.NativeObject, Int) // CHECK: try_apply [[FUNC_REF]]({{.*}}, normal bb1, error bb2 // CHECK: bb1([[NORMRET:%[0-9]+]] : $Int): // CHECK-NEXT: release_value // CHECK: bb2([[THROW:%[0-9]+]] : $any Error): // CHECK-NEXT: release_value sil [serialized] @owned_to_guaranteed_with_nothrow_caller : $@convention(thin) (Builtin.NativeObject, Int) -> Int { bb0(%0 : $Builtin.NativeObject, %1 : $Int): %f1 = function_ref @owned_to_guaranteed_with_error_result : $@convention(thin) (@owned Builtin.NativeObject, Int) -> (Int, @error Error) %r1 = apply [nothrow] %f1(%0, %1) : $@convention(thin) (@owned Builtin.NativeObject, Int) -> (Int, @error Error) return %r1 : $Int } //======================================================================= // dont convert @owned => @guaranteed when there is a dealloc_partial_ref sil @test_dealloc_partial_ref_callee : $@convention(thin) () -> ((), @error Error) // CHECK-LABEL: sil hidden @test_dealloc_partial_ref : $@convention(thin) (@owned foo) -> (@owned foo, @error any Error) { // CHECK-NOT: @guaranteed // CHECK: function_ref @test_dealloc_partial_ref_callee // CHECK-NOT: @guaranteed sil hidden @test_dealloc_partial_ref : $@convention(thin) (@owned foo) -> (@owned foo, @error Error) { bb0(%1 : $foo): strong_retain %1 : $foo %f = function_ref @test_dealloc_partial_ref_callee : $@convention(thin) () -> ((), @error Error) try_apply %f() : $@convention(thin) () -> ((), @error Error), normal bb1, error bb2 bb1(%27 : $()): strong_release %1 : $foo return %1 : $foo bb2(%157 : $Error): strong_release %1 : $foo %mt = metatype $@thick foo.Type dealloc_partial_ref %1 : $foo, %mt : $@thick foo.Type throw %157 : $Error } sil @test_dealloc_partial_ref_caller : $@convention(thin) () -> (@owned foo, @error Error) { bb0: %2 = alloc_ref $foo %3 = function_ref @test_dealloc_partial_ref : $@convention(thin) (@owned foo) -> (@owned foo, @error Error) try_apply %3(%2) : $@convention(thin) (@owned foo) -> (@owned foo, @error Error), normal bb1, error bb2 bb1(%5 : $foo): return %5 : $foo bb2(%7 : $Error): throw %7 : $Error } // CHECK: } // end sil function 'test_dealloc_partial_ref_caller' //====================== // @owned => @guaranteed // We should optimize this call. // CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @owned_to_guaranteed_simple_singlebb_callee : $@convention(thin) (@owned Builtin.NativeObject) -> () { // CHECK: [[FUNC_REF:%[0-9]+]] = function_ref @$s42owned_to_guaranteed_simple_singlebb_calleeTfq4g_n : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () // CHECK: apply [[FUNC_REF]] // CHECK-NOT: fix_lifetime // CHECK: release_value sil [serialized] @owned_to_guaranteed_simple_singlebb_callee : $@convention(thin) (@owned Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %1 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () apply %1(%0) : $@convention(thin) (Builtin.NativeObject) -> () release_value %0 : $Builtin.NativeObject %2 = tuple() return %2 : $() } // Callee to make sure we handle multiple callees properly. // CHECK-LABEL: sil [serialized] @owned_to_guaranteed_simple_singlebb_caller1 : $@convention(thin) (Builtin.NativeObject) -> () { // CHECK-NOT: fix_lifetime // CHECK: release_value sil [serialized] @owned_to_guaranteed_simple_singlebb_caller1 : $@convention(thin) (Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %1 = function_ref @owned_to_guaranteed_simple_singlebb_callee : $@convention(thin) (@owned Builtin.NativeObject) -> () apply %1(%0) : $@convention(thin) (@owned Builtin.NativeObject) -> () %2 = tuple() return %2 : $() } // CHECK-LABEL: sil [serialized] @owned_to_guaranteed_simple_singlebb_caller2 : $@convention(thin) (Builtin.NativeObject) -> () { // CHECK-NOT: fix_lifetime // CHECK: release_value sil [serialized] @owned_to_guaranteed_simple_singlebb_caller2 : $@convention(thin) (Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %1 = function_ref @owned_to_guaranteed_simple_singlebb_callee : $@convention(thin) (@owned Builtin.NativeObject) -> () apply %1(%0) : $@convention(thin) (@owned Builtin.NativeObject) -> () %2 = tuple() return %2 : $() } // We should not optimize this call due to the user. // CHECK-LABEL: sil [serialized] @owned_to_guaranteed_sideeffectblock_singlebb_callee // CHECK-NOT: @guaranteed // CHECK: return sil [serialized] @owned_to_guaranteed_sideeffectblock_singlebb_callee : $@convention(thin) (@owned Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 release_value %0 : $Builtin.NativeObject %1 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () apply %1(%0) : $@convention(thin) (Builtin.NativeObject) -> () %2 = tuple() return %2 : $() } // We should be able to optimize this callee since the release is in the exit // BB. Additionally this test makes sure that we delete dead parameters before // invalidating the owned argument -> release map. // CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @owned_to_guaranteed_multibb_callee_with_release_in_exit : $@convention(thin) (Builtin.Int1, @owned Builtin.NativeObject) -> () { // CHECK-NOT: fix_lifetime // CHECK: release_value %1 : $Builtin.NativeObject sil [serialized] @owned_to_guaranteed_multibb_callee_with_release_in_exit : $@convention(thin) (Builtin.Int1, @owned Builtin.NativeObject) -> () { bb0(%0 : $Builtin.Int1, %1 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %9999 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () apply %9999(%1) : $@convention(thin) (Builtin.NativeObject) -> () cond_br undef, bb1, bb2 bb1: br bb2 bb2: strong_release %1 : $Builtin.NativeObject %2 = tuple() return %2 : $() } // In this case the release is not in the exit, so we cannot specialize. // CHECK-LABEL: sil [serialized] @owned_to_guaranteed_multibb_callee_with_release_not_in_exit : $@convention(thin) (@owned Builtin.NativeObject) -> () { // CHECK-NOT: @guaranteed // CHECK: return sil [serialized] @owned_to_guaranteed_multibb_callee_with_release_not_in_exit : $@convention(thin) (@owned Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 strong_release %0 : $Builtin.NativeObject cond_br undef, bb1, bb2 bb1: br bb2 bb2: %1 = tuple() return %1 : $() } // CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @owned_to_guaranteed_simple_singlebb_multiple_arg_callee : $@convention(thin) (Builtin.Int1, @owned Builtin.NativeObject, Builtin.Int1) -> () { sil [serialized] @owned_to_guaranteed_simple_singlebb_multiple_arg_callee : $@convention(thin) (Builtin.Int1, @owned Builtin.NativeObject, Builtin.Int1) -> () { bb0(%0 : $Builtin.Int1, %1 : $Builtin.NativeObject, %2 : $Builtin.Int1): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %c23 = builtin "assert_configuration"() : $Builtin.Int32 %c24 = builtin "assert_configuration"() : $Builtin.Int32 %c25 = builtin "assert_configuration"() : $Builtin.Int32 %c26 = builtin "assert_configuration"() : $Builtin.Int32 %c27 = builtin "assert_configuration"() : $Builtin.Int32 %c28 = builtin "assert_configuration"() : $Builtin.Int32 %c29 = builtin "assert_configuration"() : $Builtin.Int32 %c30 = builtin "assert_configuration"() : $Builtin.Int32 %9999 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () apply %9999(%1) : $@convention(thin) (Builtin.NativeObject) -> () cond_br %0, bb1, bb2 bb1: cond_br %2, bb2, bb3 bb2: br bb3 bb3: release_value %1 : $Builtin.NativeObject %3 = tuple() return %3 : $() } // CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @owned_to_guaranteed_multibb_callee_with_release_in_exit_two_args_1 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { // CHECK: bb0([[INPUT_PTR1:%.*]] : $Builtin.NativeObject, [[INPUT_PTR2:%.*]] : $Builtin.NativeObject): // CHECK: release_value [[INPUT_PTR2]] : $Builtin.NativeObject // CHECK: release_value [[INPUT_PTR1]] : $Builtin.NativeObject sil [serialized] @owned_to_guaranteed_multibb_callee_with_release_in_exit_two_args_1 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %9999 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () apply %9999(%1) : $@convention(thin) (Builtin.NativeObject) -> () apply %9999(%0) : $@convention(thin) (Builtin.NativeObject) -> () cond_br undef, bb1, bb2 bb1: br bb2 bb2: strong_release %1 : $Builtin.NativeObject strong_release %0 : $Builtin.NativeObject %2 = tuple() return %2 : $() } // CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @owned_to_guaranteed_multibb_callee_with_release_in_exit_two_args_2 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { // CHECK: bb0([[INPUT_PTR1:%.*]] : $Builtin.NativeObject, [[INPUT_PTR2:%.*]] : $Builtin.NativeObject): // CHECK: release_value [[INPUT_PTR2]] : $Builtin.NativeObject // CHECK: release_value [[INPUT_PTR1]] : $Builtin.NativeObject sil [serialized] @owned_to_guaranteed_multibb_callee_with_release_in_exit_two_args_2 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %9999 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () apply %9999(%0) : $@convention(thin) (Builtin.NativeObject) -> () apply %9999(%1) : $@convention(thin) (Builtin.NativeObject) -> () %2 = function_ref @create_object : $@convention(thin) () -> Builtin.NativeObject %3 = apply %2() : $@convention(thin) () -> Builtin.NativeObject cond_br undef, bb1(%3 : $Builtin.NativeObject), bb2(%3 : $Builtin.NativeObject) bb1(%4 : $Builtin.NativeObject): br bb2(%4 : $Builtin.NativeObject) bb2(%5 : $Builtin.NativeObject): strong_release %5 : $Builtin.NativeObject strong_release %0 : $Builtin.NativeObject strong_release %1 : $Builtin.NativeObject %6 = tuple() return %6 : $() } // CHECK-LABEL: sil [serialized] @owned_to_guaranteed_simple_singlebb_multiple_arg_caller : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { // CHECK: bb0([[INPUT_PTR_1:%.*]] : $Builtin.NativeObject, [[INPUT_PTR_2:%.*]] : $Builtin.NativeObject): // CHECK: [[SINGLEBB_MULTIPLEARG_CALLEE:%.*]] = function_ref @$s55owned_to_guaranteed_simple_singlebb_multiple_arg_calleeTfq4ngn_n : $@convention(thin) (Builtin.Int1, @guaranteed Builtin.NativeObject, Builtin.Int1) -> () // CHECK: apply [[SINGLEBB_MULTIPLEARG_CALLEE]]({{%.*}}, [[INPUT_PTR_1]], {{%.*}}) // CHECK: release_value [[INPUT_PTR_1]] // CHECK: [[MULTIBB_RELEASENOTINEXIT_CALLEE:%.*]] = function_ref @owned_to_guaranteed_multibb_callee_with_release_not_in_exit : $@convention(thin) (@owned Builtin.NativeObject) -> () // CHECK: apply [[MULTIBB_RELEASENOTINEXIT_CALLEE]]([[INPUT_PTR_1]]) // CHECK: [[MULTIBB_RELEASEINEXIT_CALLEE:%.*]] = function_ref @$s55owned_to_guaranteed_multibb_callee_with_release_in_exitTfq4dg_n : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () // CHECK: apply [[MULTIBB_RELEASEINEXIT_CALLEE]]([[INPUT_PTR_1]]) // CHECK-NEXT: release_value [[INPUT_PTR_1]] : $Builtin.NativeObject // CHECK: [[MULTIBB_RELEASEINEXIT_TWOARGS1:%.*]] = function_ref @$s66owned_to_guaranteed_multibb_callee_with_release_in_exit_two_args_1Tfq4gg_n : $@convention(thin) (@guaranteed Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () // CHECK: apply [[MULTIBB_RELEASEINEXIT_TWOARGS1]]([[INPUT_PTR_1]], [[INPUT_PTR_2]]) // CHECK: release_value [[INPUT_PTR_2]] // CHECK: release_value [[INPUT_PTR_1]] // CHECK: [[MULTIBB_RELEASEINEXIT_TWOARGS1:%.*]] = function_ref @$s66owned_to_guaranteed_multibb_callee_with_release_in_exit_two_args_1Tfq4gg_n : $@convention(thin) (@guaranteed Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () // CHECK: apply [[MULTIBB_RELEASEINEXIT_TWOARGS1]]([[INPUT_PTR_2]], [[INPUT_PTR_1]]) // CHECK: release_value [[INPUT_PTR_1]] // CHECK: release_value [[INPUT_PTR_2]] // CHECK: [[MULTIBB_RELEASEINEXIT_TWOARGS2:%.*]] = function_ref @$s66owned_to_guaranteed_multibb_callee_with_release_in_exit_two_args_2Tfq4gg_n : $@convention(thin) (@guaranteed Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () // CHECK: apply [[MULTIBB_RELEASEINEXIT_TWOARGS2]]([[INPUT_PTR_2]], [[INPUT_PTR_1]]) // CHECK: release_value [[INPUT_PTR_1]] // CHECK: release_value [[INPUT_PTR_2]] // CHECK: [[MULTIBB_RELEASEINEXIT_TWOARGS2:%.*]] = function_ref @$s66owned_to_guaranteed_multibb_callee_with_release_in_exit_two_args_2Tfq4gg_n : $@convention(thin) (@guaranteed Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () // CHECK: apply [[MULTIBB_RELEASEINEXIT_TWOARGS2]]([[INPUT_PTR_1]], [[INPUT_PTR_2]]) // CHECK: release_value [[INPUT_PTR_2]] // CHECK: release_value [[INPUT_PTR_1]] sil [serialized] @owned_to_guaranteed_simple_singlebb_multiple_arg_caller : $@convention(thin) (Builtin.NativeObject, Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject, %1 : $Builtin.NativeObject): %2 = function_ref @owned_to_guaranteed_simple_singlebb_multiple_arg_callee : $@convention(thin) (Builtin.Int1, @owned Builtin.NativeObject, Builtin.Int1) -> () %3 = integer_literal $Builtin.Int1, 0 %4 = integer_literal $Builtin.Int1, 0 apply %2(%3, %0, %4) : $@convention(thin) (Builtin.Int1, @owned Builtin.NativeObject, Builtin.Int1) -> () %5 = function_ref @owned_to_guaranteed_multibb_callee_with_release_not_in_exit : $@convention(thin) (@owned Builtin.NativeObject) -> () apply %5(%0) : $@convention(thin) (@owned Builtin.NativeObject) -> () %6 = integer_literal $Builtin.Int1, 0 %7 = function_ref @owned_to_guaranteed_multibb_callee_with_release_in_exit : $@convention(thin) (Builtin.Int1, @owned Builtin.NativeObject) -> () apply %7(%6, %0) : $@convention(thin) (Builtin.Int1, @owned Builtin.NativeObject) -> () %8 = function_ref @owned_to_guaranteed_multibb_callee_with_release_in_exit_two_args_1 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () apply %8(%0, %1) : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () apply %8(%1, %0) : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () %9 = function_ref @owned_to_guaranteed_multibb_callee_with_release_in_exit_two_args_2 : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () apply %9(%1, %0) : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () apply %9(%0, %1) : $@convention(thin) (@owned Builtin.NativeObject, @owned Builtin.NativeObject) -> () %9999 = tuple() return %9999 : $() } // CHECK-NEGATIVE-NOT: sil {{.*}}_dont_explode_single_enum sil [noinline] @dont_explode_single_enum : $@convention(thin) (@owned Optional<(foo, foo)>) -> @owned foo { bb0(%0 : $Optional<(foo, foo)>): %281 = unchecked_enum_data %0 : $Optional<(foo, foo)>, #Optional.some!enumelt %282 = tuple_extract %281 : $(foo, foo), 0 %283 = tuple_extract %281 : $(foo, foo), 1 strong_release %283 : $foo return %282 : $foo } // CHECK-LABEL: sil @call_with_single_enum // CHECK: [[F:%[0-9]+]] = function_ref @dont_explode_single_enum : $@convention(thin) (@owned Optional<(foo, foo)>) -> @owned foo // CHECK: apply [[F]](%0) // CHECK: return // CHECK-LABEL: } // end sil function 'call_with_single_enum' sil @call_with_single_enum : $@convention(thin) (@owned Optional<(foo, foo)>) -> @owned foo { bb0(%0 : $Optional<(foo, foo)>): %f = function_ref @dont_explode_single_enum : $@convention(thin) (@owned Optional<(foo, foo)>) -> @owned foo %a = apply %f(%0) : $@convention(thin) (@owned Optional<(foo, foo)>) -> @owned foo return %a : $foo } // Check if externally available functions are optimized. sil public_external [serialized] [noinline] @externally_available_with_dead_arg : $@convention(thin) (@guaranteed foo) -> () { bb0(%0 : $foo): %r = tuple() return %r : $() } // CHECK-LABEL: sil @call_externally_available // CHECK: bb{{[0-9]+}}([[FOO:%.*]] : $foo): // CHECK: [[F:%[0-9]+]] = function_ref @$s34externally_available_with_dead_argTfq4d_n : $@convention(thin) () -> () // CHECK: apply [[F]]() // CHECK: return // CHECK-LABEL: } // end sil function 'call_externally_available' sil @call_externally_available : $@convention(thin) (@guaranteed foo) -> () { bb0(%0 : $foo): %f = function_ref @externally_available_with_dead_arg : $@convention(thin) (@guaranteed foo) -> () %a = apply %f(%0) : $@convention(thin) (@guaranteed foo) -> () %r = tuple() return %r : $() } // We should remove the array semantic from specialized calls. // CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] [_semantics "array.foobar"] @array_semantic : $@convention(method) (@owned Builtin.NativeObject) -> () { // CHECK: [[FUNC_REF:%[0-9]+]] = function_ref @$s14array_semanticTfq4g_n : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () // CHECK: apply [[FUNC_REF]] // CHECK: release_value sil [serialized] [_semantics "array.foobar"] @array_semantic : $@convention(method) (@owned Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %1 = function_ref @user : $@convention(thin) (Builtin.NativeObject) -> () apply %1(%0) : $@convention(thin) (Builtin.NativeObject) -> () release_value %0 : $Builtin.NativeObject %2 = tuple() return %2 : $() } // CHECK-LABEL: sil [serialized] @array_semantic_caller : $@convention(thin) (Builtin.NativeObject) -> () { // CHECK: [[FUNC_REF:%[0-9]+]] = function_ref @$s14array_semanticTfq4g_n : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () // CHECK: apply [[FUNC_REF]] // CHECK: release_value sil [serialized] @array_semantic_caller : $@convention(thin) (Builtin.NativeObject) -> () { bb0(%0 : $Builtin.NativeObject): %1 = function_ref @array_semantic : $@convention(method) (@owned Builtin.NativeObject) -> () apply %1(%0) : $@convention(method) (@owned Builtin.NativeObject) -> () %2 = tuple() return %2 : $() } // Make sure that we are processing in bottom up order. This test // works since the default order in which the SIL Parser places // SILFunctions into the SILModule is the order in which the function // is parsed. Thus if we are just processing in that order, s3 will // call s2 instead of s2 with the dead argument. // // CHECK-LABEL: sil [serialized] @s3 : $@convention(thin) (Builtin.Int32) -> () { // CHECK: [[FUN:%.*]] = function_ref @$s2s2Tfq4d_n // CHECK: apply [[FUN]]( sil [serialized] @s3 : $@convention(thin) (Builtin.Int32) -> () { bb0(%0 : $Builtin.Int32): %1 = function_ref @s2 : $@convention(thin) (Builtin.Int32) -> () apply %1(%0) : $@convention(thin) (Builtin.Int32) -> () %9999 = tuple() return %9999 : $() } // CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @s2 : $@convention(thin) (Builtin.Int32) -> () { sil [serialized] @s2 : $@convention(thin) (Builtin.Int32) -> () { bb0(%0 : $Builtin.Int32): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %1 = function_ref @s1 : $@convention(thin) (Builtin.Int32) -> () apply %1(%0) : $@convention(thin) (Builtin.Int32) -> () %f = function_ref @update_global: $@convention(thin) () -> () apply %f() : $@convention(thin) () -> () %9999 = tuple() return %9999 : $() } // CHECK-LABEL: sil [serialized] [signature_optimized_thunk] [always_inline] @s1 : $@convention(thin) (Builtin.Int32) -> () { sil [serialized] @s1 : $@convention(thin) (Builtin.Int32) -> () { bb0(%0 : $Builtin.Int32): // make it a non-trivial function %c1 = builtin "assert_configuration"() : $Builtin.Int32 %c2 = builtin "assert_configuration"() : $Builtin.Int32 %c3 = builtin "assert_configuration"() : $Builtin.Int32 %c4 = builtin "assert_configuration"() : $Builtin.Int32 %c5 = builtin "assert_configuration"() : $Builtin.Int32 %c6 = builtin "assert_configuration"() : $Builtin.Int32 %c7 = builtin "assert_configuration"() : $Builtin.Int32 %c8 = builtin "assert_configuration"() : $Builtin.Int32 %c9 = builtin "assert_configuration"() : $Builtin.Int32 %c10 = builtin "assert_configuration"() : $Builtin.Int32 %c11 = builtin "assert_configuration"() : $Builtin.Int32 %c12 = builtin "assert_configuration"() : $Builtin.Int32 %c13 = builtin "assert_configuration"() : $Builtin.Int32 %c14 = builtin "assert_configuration"() : $Builtin.Int32 %c15 = builtin "assert_configuration"() : $Builtin.Int32 %c16 = builtin "assert_configuration"() : $Builtin.Int32 %c17 = builtin "assert_configuration"() : $Builtin.Int32 %c18 = builtin "assert_configuration"() : $Builtin.Int32 %c19 = builtin "assert_configuration"() : $Builtin.Int32 %c20 = builtin "assert_configuration"() : $Builtin.Int32 %c21 = builtin "assert_configuration"() : $Builtin.Int32 %c22 = builtin "assert_configuration"() : $Builtin.Int32 %9999 = tuple() return %9999 : $() } // CHECK-LABEL: sil hidden [signature_optimized_thunk] [always_inline] @generic_owned_to_guaranteed : $@convention(thin) (@owned T) -> Int64 // CHECK: function_ref @$s27generic_owned_to_guaranteedTf4g_n // CHECK: apply // CHECK: release_value // CHECK: end sil function 'generic_owned_to_guaranteed' // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @generic_owned_to_guaranteed_caller : $@convention(thin) (@owned T) -> Int64 // CHECK: function_ref @$s34generic_owned_to_guaranteed_callerTf4g_n // CHECK: apply // CHECK: release_value // CHECK: end sil function 'generic_owned_to_guaranteed_caller' sil hidden [noinline] @generic_owned_to_guaranteed : $@convention(thin) (@owned T) -> Int64 { bb0(%0 : $T): %2 = witness_method $T, #KlassFoo.bar : (Self) -> () -> Int64 : $@convention(witness_method: KlassFoo) <τ_0_0 where τ_0_0 : KlassFoo> (@guaranteed τ_0_0) -> Int64 %3 = apply %2(%0) : $@convention(witness_method: KlassFoo) <τ_0_0 where τ_0_0 : KlassFoo> (@guaranteed τ_0_0) -> Int64 strong_release %0 : $T return %3 : $Int64 } sil @generic_owned_to_guaranteed_caller : $@convention(thin) (@owned T) -> Int64 { bb0(%0 : $T): %2 = function_ref @generic_owned_to_guaranteed : $@convention(thin) <τ_0_0 where τ_0_0 : KlassFoo> (@owned τ_0_0) -> Int64 strong_retain %0 : $T %4 = apply %2(%0) : $@convention(thin) <τ_0_0 where τ_0_0 : KlassFoo> (@owned τ_0_0) -> Int64 %5 = function_ref @generic_owned_to_guaranteed : $@convention(thin) <τ_0_0 where τ_0_0 : KlassFoo> (@owned τ_0_0) -> Int64 strong_retain %0 : $T %7 = apply %5(%0) : $@convention(thin) <τ_0_0 where τ_0_0 : KlassFoo> (@owned τ_0_0) -> Int64 %8 = struct_extract %4 : $Int64, #Int64._value %9 = struct_extract %7 : $Int64, #Int64._value %10 = integer_literal $Builtin.Int1, -1 %11 = builtin "sadd_with_overflow_Int64"(%8 : $Builtin.Int64, %9 : $Builtin.Int64, %10 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) %12 = tuple_extract %11 : $(Builtin.Int64, Builtin.Int1), 0 %13 = tuple_extract %11 : $(Builtin.Int64, Builtin.Int1), 1 cond_fail %13 : $Builtin.Int1 %15 = struct $Int64 (%12 : $Builtin.Int64) strong_release %0 : $T return %15 : $Int64 } // CHECK-LABEL: sil hidden [signature_optimized_thunk] [always_inline] @generic_in_to_guaranteed : $@convention(thin) (@in T) -> Int64 // CHECK: function_ref @$s24generic_in_to_guaranteedTf4g_n // CHECK: apply // CHECK: destroy_addr // CHECK: end sil function 'generic_in_to_guaranteed' // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @generic_in_to_guaranteed_caller : $@convention(thin) (@in T) -> Int64 // CHECK: function_ref @$s31generic_in_to_guaranteed_callerTf4g_n // CHECK: apply // CHECK: destroy_addr // CHECK: end sil function 'generic_in_to_guaranteed_caller' sil hidden [noinline] @generic_in_to_guaranteed : $@convention(thin) (@in T) -> Int64 { bb0(%0 : $*T): %2 = witness_method $T, #P.foo : (Self) -> () -> Int64 : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int64 %3 = apply %2(%0) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int64 destroy_addr %0 : $*T return %3 : $Int64 } sil @generic_in_to_guaranteed_caller : $@convention(thin) (@in T) -> Int64 { bb0(%0 : $*T): %2 = function_ref @generic_in_to_guaranteed : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> Int64 %3 = alloc_stack $T copy_addr %0 to [init] %3 : $*T %5 = apply %2(%3) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> Int64 dealloc_stack %3 : $*T %7 = apply %2(%0) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> Int64 %8 = struct_extract %5 : $Int64, #Int64._value %9 = struct_extract %7 : $Int64, #Int64._value %10 = integer_literal $Builtin.Int1, -1 %11 = builtin "sadd_with_overflow_Int64"(%8 : $Builtin.Int64, %9 : $Builtin.Int64, %10 : $Builtin.Int1) : $(Builtin.Int64, Builtin.Int1) %12 = tuple_extract %11 : $(Builtin.Int64, Builtin.Int1), 0 %13 = tuple_extract %11 : $(Builtin.Int64, Builtin.Int1), 1 cond_fail %13 : $Builtin.Int1 %15 = struct $Int64 (%12 : $Builtin.Int64) return %15 : $Int64 } // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @generic_func_with_dead_non_generic_arg : $@convention(thin) (@owned foo, @in T) -> () // CHECK: function_ref @$s027generic_func_with_dead_non_A4_argTf4dd_n : $@convention(thin) () -> () // Call the specialization which is not polymorphic. // CHECK: apply // CHECK: destroy_addr // CHECK: end sil function 'generic_func_with_dead_non_generic_arg' sil [noinline] @generic_func_with_dead_non_generic_arg : $@convention(thin) (@owned foo, @in T) -> () { bb0(%0 : $foo, %1 : $*T): destroy_addr %1 : $*T %r = tuple() return %r : $() } // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @generic_func_with_dead_generic_arg : $@convention(thin) (Int64, @in T) -> Int64 // CHECK: function_ref @$s023generic_func_with_dead_A4_argTf4nd_n : $@convention(thin) (Int64) -> Int64 // Call the specialization which is not polymorphic. // CHECK: apply // CHECK: destroy_addr // CHECK: end sil function 'generic_func_with_dead_generic_arg' sil [noinline] @generic_func_with_dead_generic_arg : $@convention(thin) (Int64, @in T) -> Int64 { bb0(%0 : $Int64, %1 : $*T): destroy_addr %1 : $*T return %0 : $Int64 } // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @generic_func_with_unused_generic_param_and_non_generic_arg : $@convention(thin) (Int64) -> Int64 // CHECK: function_ref @$s025generic_func_with_unused_a15_param_and_non_A4_argTf4n_n : $@convention(thin) (Int64) -> Int64 // Call the specialization which is not polymorphic. // CHECK: apply // CHECK: end sil function 'generic_func_with_unused_generic_param_and_non_generic_arg' sil [noinline] @generic_func_with_unused_generic_param_and_non_generic_arg : $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): return %0 : $Int64 } sil [noinline] @generic_func_with_unused_generic_param_and_non_generic_arg_caller : $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): %f = function_ref @generic_func_with_unused_generic_param_and_non_generic_arg : $@convention(thin) (Int64) -> Int64 %r = apply %f(%0) : $@convention(thin) (Int64) -> Int64 return %r : $Int64 } // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @generic_func_with_unused_generic_param_and_dead_non_generic_arg : $@convention(thin) (Int64, Int64) -> Int64 // CHECK: function_ref @$s025generic_func_with_unused_a20_param_and_dead_non_A4_argTf4nd_n : $@convention(thin) (Int64) -> Int64 // Call the specialization which is not polymorphic. // CHECK: apply // CHECK: end sil function 'generic_func_with_unused_generic_param_and_dead_non_generic_arg' sil [noinline] @generic_func_with_unused_generic_param_and_dead_non_generic_arg : $@convention(thin) (Int64, Int64) -> Int64 { bb0(%0 : $Int64, %1 : $Int64): return %0 : $Int64 } sil [noinline] @generic_func_with_unused_generic_param_and_dead_non_generic_arg_caller : $@convention(thin) (Int64) -> Int64 { bb0(%0 : $Int64): %f = function_ref @generic_func_with_unused_generic_param_and_dead_non_generic_arg : $@convention(thin) (Int64, Int64) -> Int64 %r = apply %f(%0, %0) : $@convention(thin) (Int64, Int64) -> Int64 return %r : $Int64 } // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @generic_func_with_unused_generic_param_and_dead_generic_arg : $@convention(thin) (@in_guaranteed T) -> () // CHECK: function_ref @$s025generic_func_with_unused_a16_param_and_dead_A4_argTf4d_n : $@convention(thin) () -> () // Call the specialization which is not polymorphic. // CHECK: apply // CHECK: end sil function 'generic_func_with_unused_generic_param_and_dead_generic_arg' sil [noinline] @generic_func_with_unused_generic_param_and_dead_generic_arg : $@convention(thin) (@in_guaranteed T) -> () { bb0(%0 : $*T): %r = tuple() return %r : $() } sil [noinline] @generic_func_with_unused_generic_param_and_dead_generic_arg_caller : $@convention(thin) (@in_guaranteed T) -> () { bb0(%0 : $*T): %f = function_ref @generic_func_with_unused_generic_param_and_dead_generic_arg : $@convention(thin) (@in_guaranteed T) -> () apply %f(%0) : $@convention(thin) (@in_guaranteed T) -> () %r = tuple() return %r : $() } // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @generic_func_with_unused_generic_param_and_dead_owned_generic_arg : $@convention(thin) (@owned T) -> () // CHECK: function_ref @$s025generic_func_with_unused_a22_param_and_dead_owned_A4_argTf4d_n : $@convention(thin) () -> () // Call the specialization which is not polymorphic. // CHECK: apply // CHECK: release_value %0 // CHECK: end sil function 'generic_func_with_unused_generic_param_and_dead_owned_generic_arg' sil [noinline] @generic_func_with_unused_generic_param_and_dead_owned_generic_arg : $@convention(thin) (@owned T) -> () { bb0(%0 : $T): release_value %0 : $T %r = tuple() return %r : $() } sil [noinline] @generic_func_with_unused_generic_param_and_dead_owned_generic_arg_caller : $@convention(thin) (@owned T) -> () { bb0(%0 : $T): %f = function_ref @generic_func_with_unused_generic_param_and_dead_owned_generic_arg : $@convention(thin) (@owned T) -> () apply %f(%0) : $@convention(thin) (@owned T) -> () %r = tuple() return %r : $() } // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @generic_func_with_multple_generic_args_and_dead_generic_arg : $@convention(thin) (@in T, @in S) -> () // CHECK: function_ref @$s026generic_func_with_multple_a15_args_and_dead_A4_argTf4nd_n : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0) -> () // Call the specialization which has only one function argument, because another one is dead // and was eliminated. // CHECK: apply // CHECK: end sil function 'generic_func_with_multple_generic_args_and_dead_generic_arg' sil [noinline] @generic_func_with_multple_generic_args_and_dead_generic_arg : $@convention(thin) (@in T, @in S) -> () { bb0(%0 : $*T, %1 : $*S): %f = function_ref @use_Generic : $@convention(thin) (@in_guaranteed T) -> () apply %f(%0) : $@convention(thin) (@in_guaranteed T) -> () %r = tuple() return %r : $() } sil [noinline] @generic_func_with_multple_generic_args_and_dead_generic_arg_caller : $@convention(thin) (@in T) -> () { bb0(%0 : $*T): %2 = alloc_stack $T copy_addr %0 to [init] %2 : $*T %4 = alloc_stack $T copy_addr %0 to [init] %4 : $*T %f = function_ref @generic_func_with_multple_generic_args_and_dead_generic_arg : $@convention(thin) (@in T, @in S) -> () apply %f(%2, %4) : $@convention(thin) (@in T, @in S) -> () dealloc_stack %4 : $*T dealloc_stack %2 : $*T %r = tuple() return %r : $() } // CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @value_generic_count : $@convention(thin) (ValueGenericType) -> Int // CHECK: function_ref @$s19value_generic_countTf4d_n : $@convention(thin) () -> Int // CHECK: apply // CHECK: } // end sil function 'value_generic_count' sil [noinline] @value_generic_count : $@convention(thin) (ValueGenericType) -> Int { bb0(%0 : $ValueGenericType): %1 = type_value $Int for N return %1 : $Int } // CHECK-LABEL: sil [noinline] @value_generic_count_caller : $@convention(thin) (ValueGenericType) -> Int // CHECK: function_ref @$s19value_generic_countTf4d_n : $@convention(thin) () -> Int // CHECK: apply // CHECK: } // end sil function 'value_generic_count_caller' sil [noinline] @value_generic_count_caller : $@convention(thin) (ValueGenericType) -> Int { bb0(%0 : $ValueGenericType): %1 = function_ref @value_generic_count : $@convention(thin) (ValueGenericType<τ_0_0>) -> Int %2 = apply %1(%0) : $@convention(thin) (ValueGenericType<τ_0_0>) -> Int return %2 : $Int } struct NE : ~Escapable where T : ~Escapable { @_lifetime(copy t) init(_ t: borrowing T) } // CHECK-NOT: sil [serialized] [signature_optimized_thunk] [always_inline] @neinit : sil [noinline] @neinit : $@convention(method) (@in_guaranteed T, @thin NE.Type) -> @lifetime(copy 0) @owned NE { bb0(%0 : @noImplicitCopy $*T, %1 : $@thin NE.Type): debug_value [moveable_value_debuginfo] %0, let, name "t", argno 1, expr op_deref %3 = struct $NE () return %3 } sil hidden @neinit_caller : $@convention(thin) (@in_guaranteed T) -> @lifetime(copy 0) @owned NE { bb0(%0 : @noImplicitCopy $*T): debug_value [moveable_value_debuginfo] %0, let, name "t", argno 1, expr op_deref %2 = metatype $@thin NE.Type %3 = function_ref @neinit : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed τ_0_0, @thin NE<τ_0_0>.Type) -> @lifetime(copy 0) @owned NE<τ_0_0> %4 = apply %3(%0, %2) : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed τ_0_0, @thin NE<τ_0_0>.Type) -> @lifetime(copy 0) @owned NE<τ_0_0> return %4 } // CHECK-LABEL: sil shared @$s36exploded_release_to_guaranteed_paramTf4gX_n // CHECK: bb0([[INPUT_ARG0:%[0-9]+]] : $Int): // CHECK-NOT: strong_release // CHECK: return // CHECK-LABEL: sil shared @$s25single_owned_return_valueTf4n_g : $@convention(thin) (@owned boo) -> boo // CHECK: bb0([[INPUT_ARG0:%[0-9]+]] : $boo): // CHECK-NOT: retain_value // CHECK: return // There should not be a single retain in this function. // // CHECK-LABEL: sil shared @$s45single_owned_return_value_with_self_recursionTf4n_g : $@convention(thin) (@owned boo) -> boo // CHECK: bb0 // CHECK-NOT: retain_value // CHECK: return // CHECK-LABEL: @$s41owned_to_unowned_retval_with_error_resultTfq4n_g : $@convention(thin) (@owned boo) -> (boo, @error any Error) { // CHECK: bb2 // CHECK: retain_value // CHECK: throw // Check that we specialized this function by removing the dead argument and // copied everything appropriately. // CHECK-LABEL: sil shared [serialized] @$s23dead_arg_with_callsitesTfq4dn_n : $@convention(thin) (Builtin.NativeObject) -> () { // CHECK: bb0([[INPUT_ARG:%[0-9]+]] : $Builtin.NativeObject): // CHECK: cond_br undef, bb1, bb2 // CHECK: bb1: // CHECK-NEXT: br bb3 // CHECK: bb2: // CHECK-NEXT: br bb3 // CHECK: bb3: // CHECK-NEXT: function_ref // CHECK-NEXT: function_ref @user // CHECK-NEXT: apply // CHECK-NEXT: tuple // CHECK-NEXT: return // CHECK-LABEL: sil private @$s31private_dead_arg_with_callsitesTf4dn_n : $@convention(thin) (Builtin.NativeObject) -> () { // CHECK: bb0( // CHECK-LABEL: sil shared [serialized] @$s37owned_to_guaranteed_with_error_resultTfq4gn_n : $@convention(thin) (@guaranteed Builtin.NativeObject, Int) -> (Int, @error any Error) { // CHECK-NOT: release // CHECK: throw // CHECK-LABEL: sil shared [serialized] @$s42owned_to_guaranteed_simple_singlebb_calleeTfq4g_n : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () { // CHECK-LABEL: sil shared [serialized] @$s55owned_to_guaranteed_multibb_callee_with_release_in_exitTfq4dg_n : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () { // CHECK: bb0( // CHECK: function_ref user // CHECK: function_ref @user // CHECK: apply // CHECK: cond_br undef, bb1, bb2 // CHECK: bb1: // CHECK-NEXT: br bb2 // CHECK: bb2: // CHECK-NEXT: tuple // CHECK-NEXT: return // Check that we have remove the array semantic attribute from the specialized // function. // Also make sure we have change the calling convention to freestanding from // method because we have changed the self argument. // CHECK-LABEL: sil shared [serialized] @$s14array_semanticTfq4g_n : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () { // CHECK: bb0(%0 : $Builtin.NativeObject) // CHECK: function_ref user // CHECK: function_ref @user // CHECK: apply // CHECK: tuple // CHECK: return // Check that an owned-to-guaranteed has happened. // CHECK-LABEL: sil shared [noinline] @$s27generic_owned_to_guaranteedTf4g_n : $@convention(thin) (@guaranteed T) -> Int64 // CHECK-NOT: release_value // CHECK-NOT: strong_release // CHECK-NOT: destroy_addr // CHECK: end sil function '$s27generic_owned_to_guaranteedTf4g_n' // Check that an owned-to-guaranteed has happened. // CHECK-LABEL: sil shared @$s34generic_owned_to_guaranteed_callerTf4g_n : $@convention(thin) (@guaranteed T) -> Int64 // Call the specialized function. It should have a guaranteed param now. // CHECK: function_ref @$s27generic_owned_to_guaranteedTf4g_n : $@convention(thin) <τ_0_0 where τ_0_0 : KlassFoo> (@guaranteed τ_0_0) -> Int64 // CHECK: apply // CHECK: end sil function '$s34generic_owned_to_guaranteed_callerTf4g_n' // Check that a in-to-guaranteed has happened. // CHECK-LABEL: sil shared [noinline] @$s24generic_in_to_guaranteedTf4g_n : $@convention(thin) (@in_guaranteed T) -> Int64 // CHECK-NOT: destroy_addr // CHECK: end sil function '$s24generic_in_to_guaranteedTf4g_n' // Check that a in-to-guaranteed has happened. // CHECK-LABEL: sil shared @$s31generic_in_to_guaranteed_callerTf4g_n : $@convention(thin) (@in_guaranteed T) -> Int64 // Call the specialized function. It should have a guaranteed param now. // CHECK: function_ref @$s24generic_in_to_guaranteedTf4g_n : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int64 // CHECK: apply // CHECK: end sil function '$s31generic_in_to_guaranteed_callerTf4g_n' // CHECK-LABEL: sil shared [noinline] @$s19value_generic_countTf4d_n : $@convention(thin) () -> Int { // CHECK: [[TYPE_VALUE:%.*]] = type_value $Int for N // CEHCK-NOT: type_value $Int for @error_type N // CHECK-NEXT: return [[TYPE_VALUE]] : $Int // CHECK-LABEL: } // end sil function '$s19value_generic_countTf4d_n'