Files
swift-mirror/test/SILOptimizer/functionsigopts.sil
Meghana Gupta 1e6f93e0e1 Disable function signature optimization on functions with lifetime dependencies
If a function has lifetime dependencies, disable FSO's dead param optimization. Dead params maybe dependency sources and we should not delete them. It is also problematic to dead code params that are not dependency sources, since lifetime dependent sources are stored as indices and deleting dead parameters will require recomputation of these indices.
2025-07-10 11:35:23 -07:00

1965 lines
94 KiB
Plaintext

// 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<let N: Int> {}
sil @use_Int : $@convention(thin) (Int) -> ()
sil @use_Int64 : $@convention(thin) (Int64) -> ()
sil @use_Generic : $@convention(thin) <T>(@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) <T where T : KlassFoo> (@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) <T where T : KlassFoo> (@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) <T where T : KlassFoo> (@owned T) -> Int64 {
bb0(%0 : $T):
%2 = witness_method $T, #KlassFoo.bar : <Self where Self : KlassFoo> (Self) -> () -> Int64 : $@convention(witness_method: KlassFoo) <τ_0_0 where τ_0_0 : KlassFoo> (@guaranteed τ_0_0) -> Int64
%3 = apply %2<T>(%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) <T where T : KlassFoo> (@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<T>(%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<T>(%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) <T where T : P> (@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) <T where T : P> (@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) <T where T : P> (@in T) -> Int64 {
bb0(%0 : $*T):
%2 = witness_method $T, #P.foo : <Self where Self : P> (Self) -> () -> Int64 : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int64
%3 = apply %2<T>(%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) <T where T : P> (@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<T>(%3) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> Int64
dealloc_stack %3 : $*T
%7 = apply %2<T>(%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) <T> (@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) <T> (@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) <T> (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) <T> (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) <T> (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) <T> (Int64) -> Int64 {
bb0(%0 : $Int64):
return %0 : $Int64
}
sil [noinline] @generic_func_with_unused_generic_param_and_non_generic_arg_caller : $@convention(thin) <T> (Int64) -> Int64 {
bb0(%0 : $Int64):
%f = function_ref @generic_func_with_unused_generic_param_and_non_generic_arg : $@convention(thin) <T> (Int64) -> Int64
%r = apply %f<T>(%0) : $@convention(thin) <T> (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) <T> (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) <T> (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) <T> (Int64) -> Int64 {
bb0(%0 : $Int64):
%f = function_ref @generic_func_with_unused_generic_param_and_dead_non_generic_arg : $@convention(thin) <T> (Int64, Int64) -> Int64
%r = apply %f<T>(%0, %0) : $@convention(thin) <T> (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) <T> (@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) <T> (@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) <T> (@in_guaranteed T) -> () {
bb0(%0 : $*T):
%f = function_ref @generic_func_with_unused_generic_param_and_dead_generic_arg : $@convention(thin) <T> (@in_guaranteed T) -> ()
apply %f<T>(%0) : $@convention(thin) <T> (@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) <T where T : KlassFoo> (@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) <T where T: KlassFoo> (@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) <T where T: KlassFoo> (@owned T) -> () {
bb0(%0 : $T):
%f = function_ref @generic_func_with_unused_generic_param_and_dead_owned_generic_arg : $@convention(thin) <T where T: KlassFoo> (@owned T) -> ()
apply %f<T>(%0) : $@convention(thin) <T where T: KlassFoo> (@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) <T, S> (@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) <T, S> (@in T, @in S) -> () {
bb0(%0 : $*T, %1 : $*S):
%f = function_ref @use_Generic : $@convention(thin) <T>(@in_guaranteed T) -> ()
apply %f<T>(%0) : $@convention(thin) <T>(@in_guaranteed T) -> ()
%r = tuple()
return %r : $()
}
sil [noinline] @generic_func_with_multple_generic_args_and_dead_generic_arg_caller : $@convention(thin) <T> (@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) <T, S> (@in T, @in S) -> ()
apply %f<T, T>(%2, %4) : $@convention(thin) <T, S> (@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) <let N : Int> (ValueGenericType<N>) -> Int
// CHECK: function_ref @$s19value_generic_countTf4d_n : $@convention(thin) <let τ_0_0 : Int> () -> Int
// CHECK: apply
// CHECK: } // end sil function 'value_generic_count'
sil [noinline] @value_generic_count : $@convention(thin) <let N : Int> (ValueGenericType<N>) -> Int {
bb0(%0 : $ValueGenericType<N>):
%1 = type_value $Int for N
return %1 : $Int
}
// CHECK-LABEL: sil [noinline] @value_generic_count_caller : $@convention(thin) <let N : Int> (ValueGenericType<N>) -> Int
// CHECK: function_ref @$s19value_generic_countTf4d_n : $@convention(thin) <let τ_0_0 : Int> () -> Int
// CHECK: apply
// CHECK: } // end sil function 'value_generic_count_caller'
sil [noinline] @value_generic_count_caller : $@convention(thin) <let N : Int> (ValueGenericType<N>) -> Int {
bb0(%0 : $ValueGenericType<N>):
%1 = function_ref @value_generic_count : $@convention(thin) <let τ_0_0 : Int> (ValueGenericType<τ_0_0>) -> Int
%2 = apply %1<N>(%0) : $@convention(thin) <let τ_0_0 : Int> (ValueGenericType<τ_0_0>) -> Int
return %2 : $Int
}
struct NE<T> : ~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) <T where T : ~Escapable> (@in_guaranteed T, @thin NE<T>.Type) -> @lifetime(copy 0) @owned NE<T> {
bb0(%0 : @noImplicitCopy $*T, %1 : $@thin NE<T>.Type):
debug_value [moveable_value_debuginfo] %0, let, name "t", argno 1, expr op_deref
%3 = struct $NE<T> ()
return %3
}
sil hidden @neinit_caller : $@convention(thin) <T where T : ~Escapable> (@in_guaranteed T) -> @lifetime(copy 0) @owned NE<T> {
bb0(%0 : @noImplicitCopy $*T):
debug_value [moveable_value_debuginfo] %0, let, name "t", argno 1, expr op_deref
%2 = metatype $@thin NE<T>.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<T>(%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) <T where T : KlassFoo> (@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) <T where T : KlassFoo> (@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) <T where T : P> (@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) <T where T : P> (@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) <let N : Int> () -> 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'