| // RUN: %target-sil-opt -enable-sil-verify-all -generic-specializer %s | FileCheck %s |
| |
| sil_stage canonical |
| |
| import Builtin |
| import Swift |
| |
| // CHECK-LABEL: sil @_TF10specialize4exp1FT_T_ : $@convention(thin) () -> () { |
| // CHECK-NOT: apply |
| // CHECK: [[CTOR:%[0-9]+]] = function_ref @_TTSg5Vs5Int32___TFV10specialize3XXXCU__fMGS0_Q__FT1tQ__GS0_Q__ |
| // CHECK: apply [[CTOR]] |
| // CHECK: [[ACCEPTS_INT:%[0-9]+]] = function_ref @_TF10specialize10acceptsIntFSiT_ |
| // CHECK: [[FOO:%[0-9]+]] = function_ref @_TTSg5Vs5Int32___TFV10specialize3XXX3fooU__fRGS0_Q__FT1tQ__Si |
| // CHECK: apply [[FOO]] |
| // CHECK: apply [[ACCEPTS_INT]] |
| // CHECK: return |
| // CHEcK: sil @_TF10specialize4exp2FT_T_ : $@convention(thin) () -> () { |
| |
| struct XXX<T> { |
| init(t: T) |
| mutating func foo(t: T) -> Int32 |
| var m_t: T |
| } |
| |
| // top_level_code |
| sil private @top_level_code : $@convention(thin) () -> () { |
| bb0: |
| %0 = tuple () // user: %1 |
| return %0 : $() // id: %1 |
| } |
| |
| // specialize.XXX.init <A>(specialize.XXX<A>.Type)(t : A) -> specialize.XXX<A> |
| sil [noinline] @_TFV10specialize3XXXCU__fMGS0_Q__FT1tQ__GS0_Q__ : $@convention(thin) <T> (@in T, @thin XXX<T>.Type) -> @out XXX<T> { |
| bb0(%0 : $*XXX<T>, %1 : $*T, %2 : $@thin XXX<T>.Type): |
| %3 = alloc_stack $XXX<T>, var, name "sf" // users: %7, %11, %13 |
| debug_value_addr %1 : $*T, let, name "t" // id: %4 |
| %5 = alloc_stack $T // users: %6, %8, %9 |
| copy_addr %1 to [initialization] %5 : $*T // id: %6 |
| %7 = struct_element_addr %3 : $*XXX<T>, #XXX.m_t // user: %8 |
| copy_addr [take] %5 to [initialization] %7 : $*T // id: %8 |
| dealloc_stack %5 : $*T // id: %9 |
| destroy_addr %1 : $*T // id: %10 |
| copy_addr [take] %3 to [initialization] %0 : $*XXX<T> // id: %11 |
| %12 = tuple () // user: %14 |
| dealloc_stack %3 : $*XXX<T> // id: %13 |
| return %12 : $() // id: %14 |
| } |
| |
| // specialize.XXX.foo <A>(@inout specialize.XXX<A>)(t : A) -> Swift.Int32 |
| sil [noinline] @_TFV10specialize3XXX3fooU__fRGS0_Q__FT1tQ__Si : $@convention(method) <T> (@in T, @inout XXX<T>) -> Int32 { |
| bb0(%0 : $*T, %1 : $*XXX<T>): |
| debug_value_addr %0 : $*T, let, name "t" // id: %2 |
| %3 = alloc_stack $T // users: %4, %6, %7 |
| copy_addr %0 to [initialization] %3 : $*T // id: %4 |
| %5 = struct_element_addr %1 : $*XXX<T>, #XXX.m_t // user: %6 |
| copy_addr [take] %3 to %5 : $*T // id: %6 |
| dealloc_stack %3 : $*T // id: %7 |
| %8 = integer_literal $Builtin.Int32, 4 // user: %9 |
| %9 = struct $Int32 (%8 : $Builtin.Int32) // user: %11 |
| destroy_addr %0 : $*T // id: %10 |
| return %9 : $Int32 // id: %11 |
| } |
| |
| // Swift.Int32._convertFromBuiltinIntegerLiteral (Swift.Int32.Type)(Builtin.Int2048) -> Swift.Int32 |
| sil public_external [transparent] @_TFSi33_convertFromBuiltinIntegerLiteralfMSiFBi2048_Si : $@convention(thin) (Builtin.Int2048, @thin Int32.Type) -> Int32 { |
| bb0(%0 : $Builtin.Int2048, %1 : $@thin Int32.Type): |
| %3 = builtin "s_to_s_checked_trunc_Int2048_Int32"(%0 : $Builtin.Int2048) : $(Builtin.Int32, Builtin.Int1) |
| %4 = tuple_extract %3 : $(Builtin.Int32, Builtin.Int1), 0 // user: %5 |
| %5 = struct $Int32 (%4 : $Builtin.Int32) // user: %6 |
| return %5 : $Int32 // id: %6 |
| } |
| |
| // specialize.acceptsInt (Swift.Int32) -> () |
| sil [noinline] @_TF10specialize10acceptsIntFSiT_ : $@convention(thin) (Int32) -> () { |
| bb0(%0 : $Int32): |
| debug_value %0 : $Int32, let, name "x" // id: %1 |
| %2 = tuple () // user: %3 |
| return %2 : $() // id: %3 |
| } |
| |
| // specialize.exp1 () -> () |
| sil @_TF10specialize4exp1FT_T_ : $@convention(thin) () -> () { |
| bb0: |
| %0 = alloc_stack $XXX<Int32>, var, name "II" // users: %7, %15, %19 |
| // function_ref specialize.XXX.init <A>(specialize.XXX<A>.Type)(t : A) -> specialize.XXX<A> |
| %1 = function_ref @_TFV10specialize3XXXCU__fMGS0_Q__FT1tQ__GS0_Q__ : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> // user: %7 |
| %2 = metatype $@thin XXX<Int32>.Type // user: %7 |
| %3 = alloc_stack $Int32 // users: %6, %7, %8 |
| %4 = integer_literal $Builtin.Int32, 5 // user: %5 |
| %5 = struct $Int32 (%4 : $Builtin.Int32) // user: %6 |
| store %5 to %3 : $*Int32 // id: %6 |
| %7 = apply %1<Int32>(%0, %3, %2) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> |
| dealloc_stack %3 : $*Int32 // id: %8 |
| // function_ref specialize.acceptsInt (Swift.Int32) -> () |
| %9 = function_ref @_TF10specialize10acceptsIntFSiT_ : $@convention(thin) (Int32) -> () // user: %16 |
| // function_ref specialize.XXX.foo <A>(@inout specialize.XXX<A>)(t : A) -> Swift.Int32 |
| %10 = function_ref @_TFV10specialize3XXX3fooU__fRGS0_Q__FT1tQ__Si : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %15 |
| %11 = alloc_stack $Int32 // users: %14, %15, %17 |
| %12 = integer_literal $Builtin.Int32, 4 // user: %13 |
| %13 = struct $Int32 (%12 : $Builtin.Int32) // user: %14 |
| store %13 to %11 : $*Int32 // id: %14 |
| %15 = apply %10<Int32>(%11, %0) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16 |
| %16 = apply %9(%15) : $@convention(thin) (Int32) -> () |
| dealloc_stack %11 : $*Int32 // id: %17 |
| %18 = tuple () // user: %20 |
| dealloc_stack %0 : $*XXX<Int32> // id: %19 |
| return %18 : $() // id: %20 |
| } |
| |
| // specialize.exp2 () -> () |
| sil @_TF10specialize4exp2FT_T_ : $@convention(thin) () -> () { |
| bb0: |
| %0 = alloc_stack $XXX<UInt8>, var, name "I8" // users: %7, %15, %19 |
| // function_ref specialize.XXX.init <A>(specialize.XXX<A>.Type)(t : A) -> specialize.XXX<A> |
| %1 = function_ref @_TFV10specialize3XXXCU__fMGS0_Q__FT1tQ__GS0_Q__ : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> // user: %7 |
| %2 = metatype $@thin XXX<UInt8>.Type // user: %7 |
| %3 = alloc_stack $UInt8 // users: %6, %7, %8 |
| %4 = integer_literal $Builtin.Int8, 5 // user: %5 |
| %5 = struct $UInt8 (%4 : $Builtin.Int8) // user: %6 |
| store %5 to %3 : $*UInt8 // id: %6 |
| %7 = apply %1<UInt8>(%0, %3, %2) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> |
| dealloc_stack %3 : $*UInt8 // id: %8 |
| // function_ref specialize.acceptsInt (Swift.Int32) -> () |
| %9 = function_ref @_TF10specialize10acceptsIntFSiT_ : $@convention(thin) (Int32) -> () // user: %16 |
| // function_ref specialize.XXX.foo <A>(@inout specialize.XXX<A>)(t : A) -> Swift.Int32 |
| %10 = function_ref @_TFV10specialize3XXX3fooU__fRGS0_Q__FT1tQ__Si : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %15 |
| %11 = alloc_stack $UInt8 // users: %14, %15, %17 |
| %12 = integer_literal $Builtin.Int8, 4 // user: %13 |
| %13 = struct $UInt8 (%12 : $Builtin.Int8) // user: %14 |
| store %13 to %11 : $*UInt8 // id: %14 |
| %15 = apply %10<UInt8>(%11, %0) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16 |
| %16 = apply %9(%15) : $@convention(thin) (Int32) -> () |
| dealloc_stack %11 : $*UInt8 // id: %17 |
| %18 = tuple () // user: %20 |
| dealloc_stack %0 : $*XXX<UInt8> // id: %19 |
| return %18 : $() // id: %20 |
| } |
| |
| // Swift.UInt8.init (Swift.UInt8.Type)(Swift.Int32) -> Swift.UInt8 |
| sil public_external [transparent] @_TFVs5UInt8CfMS_FSiS_ : $@convention(thin) (Int32, @thin UInt8.Type) -> UInt8 { |
| bb0(%0 : $Int32, %1 : $@thin UInt8.Type): |
| %3 = struct_extract %0 : $Int32, #Int32._value // user: %4 |
| %4 = builtin "zextOrBitCast_Int32_Int64"(%3 : $Builtin.Int32) : $Builtin.Int64 // user: %6 |
| %6 = builtin "s_to_u_checked_trunc_Int64_Int8"(%4 : $Builtin.Int64) : $(Builtin.Int8, Builtin.Int1) // users: %7, %8 |
| %7 = tuple_extract %6 : $(Builtin.Int8, Builtin.Int1), 0 // user: %10 |
| %8 = tuple_extract %6 : $(Builtin.Int8, Builtin.Int1), 1 // user: %9 |
| cond_fail %8 : $Builtin.Int1 // id: %9 |
| %10 = struct $UInt8 (%7 : $Builtin.Int8) // user: %11 |
| return %10 : $UInt8 // id: %11 |
| } |
| |
| // specialize.useClosure <A>(fun : () -> A) -> A |
| sil @_TF10specialize10useClosureU__FT3funFT_Q__Q_ : $@convention(thin) <T> (@owned @callee_owned () -> @out T) -> @out T { |
| bb0(%0 : $*T, %1 : $@callee_owned () -> @out T): |
| debug_value %1 : $@callee_owned () -> @out T, let, name "fun" // id: %2 |
| strong_retain %1 : $@callee_owned () -> @out T // id: %3 |
| %4 = apply %1(%0) : $@callee_owned () -> @out T |
| strong_release %1 : $@callee_owned () -> @out T // id: %5 |
| %6 = tuple () // user: %7 |
| return %6 : $() // id: %7 |
| } |
| |
| // specialize.getGenericClosure <A>(t : A) -> () -> A |
| sil @_TF10specialize17getGenericClosureU__FT1tQ__FT_Q_ : $@convention(thin) <T> (@in T) -> @owned @callee_owned () -> @out T { |
| bb0(%0 : $*T): |
| debug_value_addr %0 : $*T, let, name "t" // id: %1 |
| // function_ref specialize.(getGenericClosure <A>(t : A) -> () -> A).(tmp #1) (())A |
| %2 = function_ref @_TFF10specialize17getGenericClosureU__FT1tQ__FT_Q_L_3tmpfT_Q_ : $@convention(thin) <τ_0_0> (@owned @box τ_0_0) -> @out τ_0_0 // user: %5 |
| %3 = alloc_box $T // users: %4, %5, %5 |
| %3a = project_box %3 : $@box T |
| copy_addr %0 to [initialization] %3a : $*T // id: %4 |
| %5 = partial_apply %2<T>(%3) : $@convention(thin) <τ_0_0> (@owned @box τ_0_0) -> @out τ_0_0 // user: %7 |
| destroy_addr %0 : $*T // id: %6 |
| return %5 : $@callee_owned () -> @out T // id: %7 |
| } |
| |
| // specialize.(getGenericClosure <A>(t : A) -> () -> A).(tmp #1) (()) |
| sil shared @_TFF10specialize17getGenericClosureU__FT1tQ__FT_Q_L_3tmpfT_Q_ : $@convention(thin) <T> (@owned @box T) -> @out T { |
| bb0(%0 : $*T, %1 : $@box T): |
| %2 = project_box %1 : $@box T |
| copy_addr %2 to [initialization] %0 : $*T // id: %3 |
| strong_release %1 : $@box T // id: %4 |
| %5 = tuple () // user: %6 |
| return %5 : $() // id: %6 |
| } |
| |
| // specialize.specializePartialApplies () -> Swift.UInt8 |
| sil @_TF10specialize24specializePartialAppliesFT_Vs5UInt8 : $@convention(thin) () -> UInt8 { |
| bb0: |
| %0 = alloc_stack $UInt8, var, name "i" // users: %3, %18 |
| %1 = integer_literal $Builtin.Int8, 5 // user: %2 |
| %2 = struct $UInt8 (%1 : $Builtin.Int8) // users: %3, %7 |
| store %2 to %0 : $*UInt8 // id: %3 |
| // function_ref specialize.useClosure <A>(fun : () -> A) -> A |
| %4 = function_ref @_TF10specialize10useClosureU__FT3funFT_Q__Q_ : $@convention(thin) <τ_0_0> (@owned @callee_owned () -> @out τ_0_0) -> @out τ_0_0 // user: %14 |
| // function_ref specialize.getGenericClosure <A>(t : A) -> () -> A |
| %5 = function_ref @_TF10specialize17getGenericClosureU__FT1tQ__FT_Q_ : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @owned @callee_owned () -> @out τ_0_0 // user: %8 |
| %6 = alloc_stack $UInt8 // users: %7, %8, %17 |
| store %2 to %6 : $*UInt8 // id: %7 |
| %8 = apply %5<UInt8>(%6) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @owned @callee_owned () -> @out τ_0_0 // user: %10 |
| // function_ref reabstraction thunk helper from @callee_owned () -> (@out Swift.UInt8) to @callee_owned () -> (@unowned Swift.UInt8) |
| %9 = function_ref @_TTRXFo__iVs5UInt8_XFo__dS__ : $@convention(thin) (@owned @callee_owned () -> @out UInt8) -> UInt8 // user: %10 |
| %10 = partial_apply %9(%8) : $@convention(thin) (@owned @callee_owned () -> @out UInt8) -> UInt8 // user: %12 |
| // function_ref reabstraction thunk helper from @callee_owned () -> (@unowned Swift.UInt8) to @callee_owned () -> (@out Swift.UInt8) |
| %11 = function_ref @_TTRXFo__dVs5UInt8_XFo__iS__ : $@convention(thin) (@owned @callee_owned () -> UInt8) -> @out UInt8 // user: %12 |
| %12 = partial_apply %11(%10) : $@convention(thin) (@owned @callee_owned () -> UInt8) -> @out UInt8 // user: %14 |
| %13 = alloc_stack $UInt8 // users: %14, %15, %16 |
| %14 = apply %4<UInt8>(%13, %12) : $@convention(thin) <τ_0_0> (@owned @callee_owned () -> @out τ_0_0) -> @out τ_0_0 |
| %15 = load %13 : $*UInt8 // user: %19 |
| dealloc_stack %13 : $*UInt8 // id: %16 |
| dealloc_stack %6 : $*UInt8 // id: %17 |
| dealloc_stack %0 : $*UInt8 // id: %18 |
| return %15 : $UInt8 // id: %19 |
| } |
| |
| // reabstraction thunk helper from @callee_owned () -> (@out Swift.UInt8) to @callee_owned () -> (@unowned Swift.UInt8) |
| sil shared [transparent] @_TTRXFo__iVs5UInt8_XFo__dS__ : $@convention(thin) (@owned @callee_owned () -> @out UInt8) -> UInt8 { |
| bb0(%0 : $@callee_owned () -> @out UInt8): |
| %1 = alloc_stack $UInt8 // users: %2, %3, %4 |
| %2 = apply %0(%1) : $@callee_owned () -> @out UInt8 |
| %3 = load %1 : $*UInt8 // user: %5 |
| dealloc_stack %1 : $*UInt8 // id: %4 |
| return %3 : $UInt8 // id: %5 |
| } |
| |
| // reabstraction thunk helper from @callee_owned () -> (@unowned Swift.UInt8) to @callee_owned () -> (@out Swift.UInt8) |
| sil shared [transparent] @_TTRXFo__dVs5UInt8_XFo__iS__ : $@convention(thin) (@owned @callee_owned () -> UInt8) -> @out UInt8 { |
| bb0(%0 : $*UInt8, %1 : $@callee_owned () -> UInt8): |
| %2 = apply %1() : $@callee_owned () -> UInt8 // user: %3 |
| store %2 to %0 : $*UInt8 // id: %3 |
| %4 = tuple () // user: %5 |
| return %4 : $() // id: %5 |
| } |
| |
| |
| class Base { |
| } |
| sil_vtable Base { |
| } |
| |
| sil @generic_upcast : $@convention(thin) <T where T : Base> (@owned T) -> @owned Base { |
| bb0(%0 : $T): |
| %2 = upcast %0 : $T to $Base |
| return %2 : $Base |
| } |
| |
| sil @specialize_generic_upcast : $@convention(thin)(@owned Base) -> @owned Base { |
| bb0(%0 : $Base): |
| %1 = function_ref @generic_upcast : $@convention(thin)<T where T : Base> (@owned T) -> @owned Base |
| %2 = apply %1<Base>(%0) : $@convention(thin)<T where T : Base> (@owned T) -> @owned Base |
| return %2 : $Base |
| } |
| |
| // CHECK-LABEL: sil shared @_TTS{{.*}}generic_upcast : $@convention(thin) (@owned Base) -> @owned Base { |
| // CHECK: bb0(%0 : $Base): |
| // CHECK: return %0 : $Base |
| |
| |
| // Check generic specialization of partial_apply |
| |
| protocol P { func get() -> Int32 } |
| |
| struct C : P { func get() -> Int32 } |
| |
| // test4.C.get (test4.C)() -> Swift.Int32 |
| sil hidden @_TFV5test41C3getfS0_FT_Vs5Int32 : $@convention(method) (C) -> Int32 { |
| bb0(%0 : $C): |
| debug_value %0 : $C, let, name "self" // id: %1 |
| %2 = integer_literal $Builtin.Int32, 1 // user: %3 |
| %3 = struct $Int32 (%2 : $Builtin.Int32) // user: %4 |
| return %3 : $Int32 // id: %4 |
| } |
| |
| // test4.C.init (test4.C.Type)() -> test4.C |
| sil hidden [noinline] @_TFV5test41CCfMS0_FT_S0_ : $@convention(thin) (@thin C.Type) -> C { |
| bb0(%0 : $@thin C.Type): |
| %1 = alloc_stack $C, var, name "sf" // user: %3 |
| %2 = struct $C () // user: %4 |
| dealloc_stack %1 : $*C // id: %3 |
| return %2 : $C // id: %4 |
| } |
| |
| // protocol witness for test4.P.get <A : test4.P>(test4.P.Self)() -> Swift.Int32 in conformance test4.C : test4.P in test4 |
| sil hidden [transparent] [thunk] @_TTWV5test41CS_1PS_FS1_3getUS1___fQPS1_FT_Vs5Int32 : $@convention(witness_method) (@in_guaranteed C) -> Int32 { |
| bb0(%0 : $*C): |
| %1 = load %0 : $*C // user: %3 |
| // function_ref test4.C.get (test4.C)() -> Swift.Int32 |
| %2 = function_ref @_TFV5test41C3getfS0_FT_Vs5Int32 : $@convention(method) (C) -> Int32 // user: %3 |
| %3 = apply %2(%1) : $@convention(method) (C) -> Int32 // user: %4 |
| return %3 : $Int32 // id: %4 |
| } |
| |
| // test4.boo <A : test4.P, B>(A) -> (Swift.Int32, B) -> Swift.Int32 |
| sil hidden [noinline] @_TF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_ : $@convention(thin) <U, T where U : P> (@in U) -> @owned @callee_owned (Int32, @in T) -> Int32 { |
| bb0(%0 : $*U): |
| debug_value_addr %0 : $*U, let, name "y" // id: %1 |
| // function_ref test4.(boo <A : test4.P, B>(A) -> (Swift.Int32, B) -> Swift.Int32).(closure #1) |
| %2 = function_ref @_TFF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_U_FTS1_Q0__S1_ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (Int32, @in τ_0_1, @owned @box τ_0_0) -> Int32 // user: %5 |
| %3 = alloc_box $U // users: %4, %5, %5 |
| %3a = project_box %3 : $@box U |
| copy_addr %0 to [initialization] %3a : $*U // id: %4 |
| %5 = partial_apply %2<U, T>(%3) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (Int32, @in τ_0_1, @owned @box τ_0_0) -> Int32 // user: %7 |
| destroy_addr %0 : $*U // id: %6 |
| return %5 : $@callee_owned (Int32, @in T) -> Int32 // id: %7 |
| } |
| |
| // test4.(boo <A : test4.P, B>(A) -> (Swift.Int32, B) -> Swift.Int32).(closure #1) |
| sil shared [noinline] @_TFF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_U_FTS1_Q0__S1_ : $@convention(thin) <U, T where U : P> (Int32, @in T, @owned @box U) -> Int32 { |
| bb0(%0 : $Int32, %1 : $*T, %2 : $@box U): |
| %3 = project_box %2 : $@box U |
| debug_value %0 : $Int32, let, name "x" // id: %4 |
| debug_value_addr %1 : $*T, let, name "z" // id: %5 |
| %6 = witness_method $U, #P.get!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %7 |
| %7 = apply %6<U>(%3) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %8 |
| %8 = struct_extract %7 : $Int32, #Int32._value // user: %11 |
| %9 = struct_extract %0 : $Int32, #Int32._value // user: %11 |
| %10 = integer_literal $Builtin.Int1, -1 // user: %11 |
| %11 = builtin "sadd_with_overflow_Int32"(%8 : $Builtin.Int32, %9 : $Builtin.Int32, %10 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) // users: %12, %13 |
| %12 = tuple_extract %11 : $(Builtin.Int32, Builtin.Int1), 0 // user: %15 |
| %13 = tuple_extract %11 : $(Builtin.Int32, Builtin.Int1), 1 // user: %14 |
| cond_fail %13 : $Builtin.Int1 // id: %14 |
| %15 = struct $Int32 (%12 : $Builtin.Int32) // user: %18 |
| strong_release %2 : $@box U // id: %16 |
| destroy_addr %1 : $*T // id: %17 |
| return %15 : $Int32 // id: %18 |
| } |
| |
| // static Swift.+ infix (Swift.Int32, Swift.Int32) -> Swift.Int32 |
| sil public_external [transparent] [fragile] @_TZFsoi1pFTVs5Int32S__S_ : $@convention(thin) (Int32, Int32) -> Int32 { |
| bb0(%0 : $Int32, %1 : $Int32): |
| %2 = struct_extract %0 : $Int32, #Int32._value // user: %5 |
| %3 = struct_extract %1 : $Int32, #Int32._value // user: %5 |
| %4 = integer_literal $Builtin.Int1, -1 // user: %5 |
| %5 = builtin "sadd_with_overflow_Int32"(%2 : $Builtin.Int32, %3 : $Builtin.Int32, %4 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) // users: %6, %7 |
| %6 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 0 // user: %9 |
| %7 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 1 // user: %8 |
| cond_fail %7 : $Builtin.Int1 // id: %8 |
| %9 = struct $Int32 (%6 : $Builtin.Int32) // user: %10 |
| return %9 : $Int32 // id: %10 |
| } |
| |
| // test4.foo <A : test4.P, B : test4.P>(A, B) -> (Swift.Int32, Swift.Float) -> Swift.Int32 |
| sil hidden [noinline] @_TF5test43fooUS_1P_S0___FTQ_Q0__FTVs5Int32Sf_S1_ : $@convention(thin) <T, U where T : P, U : P> (@in T, @in U) -> @owned @callee_owned (Int32, Float) -> Int32 { |
| bb0(%0 : $*T, %1 : $*U): |
| debug_value_addr %0 : $*T, let, name "x" // id: %2 |
| debug_value_addr %1 : $*U, let, name "y" // id: %3 |
| // function_ref test4.boo <A : test4.P, B>(A) -> (Swift.Int32, B) -> Swift.Int32 |
| %4 = function_ref @_TF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32, @in τ_0_1) -> Int32 // user: %7 |
| %5 = alloc_stack $U // users: %6, %7, %10 |
| copy_addr %1 to [initialization] %5 : $*U // id: %6 |
| %7 = apply %4<U, Float>(%5) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32, @in τ_0_1) -> Int32 // user: %9 |
| // function_ref reabstraction thunk helper <T_0_0, T_0_1 where T_0_0: test4.P, T_0_1: test4.P> from @callee_owned (@unowned Swift.Int32, @in Swift.Float) -> (@unowned Swift.Int32) to @callee_owned (@unowned Swift.Int32, @unowned Swift.Float) -> (@unowned Swift.Int32) |
| %8 = function_ref @_TTRG1_RPq_P5test41P_Pq0_PS0___XFo_dVs5Int32iSf_dS1__XFo_dS1_dSf_dS1__ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 // user: %9 |
| %9 = partial_apply %8<T, U>(%7) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 // user: %13 |
| dealloc_stack %5 : $*U // id: %10 |
| destroy_addr %1 : $*U // id: %11 |
| destroy_addr %0 : $*T // id: %12 |
| return %9 : $@callee_owned (Int32, Float) -> Int32 // id: %13 |
| } |
| |
| // reabstraction thunk helper <T_0_0, T_0_1 where T_0_0: test4.P, T_0_1: test4.P> from @callee_owned (@unowned Swift.Int32, @in Swift.Float) -> (@unowned Swift.Int32) to @callee_owned (@unowned Swift.Int32, @unowned Swift.Float) -> (@unowned Swift.Int32) |
| sil shared [transparent] [thunk] @_TTRG1_RPq_P5test41P_Pq0_PS0___XFo_dVs5Int32iSf_dS1__XFo_dS1_dSf_dS1__ : $@convention(thin) <T, U where T : P, U : P> (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 { |
| bb0(%0 : $Int32, %1 : $Float, %2 : $@callee_owned (Int32, @in Float) -> Int32): |
| %3 = alloc_stack $Float // users: %4, %5, %6 |
| store %1 to %3 : $*Float // id: %4 |
| %5 = apply %2(%0, %3) : $@callee_owned (Int32, @in Float) -> Int32 // user: %7 |
| dealloc_stack %3 : $*Float // id: %6 |
| return %5 : $Int32 // id: %7 |
| } |
| |
| // test4.gen1 <A : test4.P>(A) -> (Swift.Int32) -> Swift.Int32 |
| sil hidden [noinline] @_TF5test44gen1US_1P__FQ_FVs5Int32S1_ : $@convention(thin) <T where T : P> (@in T) -> @owned @callee_owned (Int32) -> Int32 { |
| bb0(%0 : $*T): |
| debug_value_addr %0 : $*T, let, name "x" // id: %1 |
| // function_ref test4.(gen1 <A : test4.P>(A) -> (Swift.Int32) -> Swift.Int32).(closure #1) |
| %2 = function_ref @_TFF5test44gen1US_1P__FQ_FVs5Int32S1_U_FS1_S1_ : $@convention(thin) <τ_0_0 where τ_0_0 : P> (Int32, @owned @box τ_0_0) -> Int32 // user: %5 |
| %3 = alloc_box $T // users: %4, %5, %5 |
| %3a = project_box %3 : $@box T |
| copy_addr %0 to [initialization] %3a : $*T // id: %4 |
| %5 = partial_apply %2<T>(%3) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (Int32, @owned @box τ_0_0) -> Int32 // user: %7 |
| destroy_addr %0 : $*T // id: %6 |
| return %5 : $@callee_owned (Int32) -> Int32 // id: %7 |
| } |
| |
| // test4.(gen1 <A : test4.P>(A) -> (Swift.Int32) -> Swift.Int32).(closure #1) |
| sil shared [noinline] @_TFF5test44gen1US_1P__FQ_FVs5Int32S1_U_FS1_S1_ : $@convention(thin) <T where T : P> (Int32, @owned @box T) -> Int32 { |
| bb0(%0 : $Int32, %1 : $@box T): |
| %2 = project_box %1 : $@box T |
| debug_value %0 : $Int32 , let, name "$0" // id: %3 |
| %4 = witness_method $T, #P.get!1 : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %5 |
| %5 = apply %4<T>(%2) : $@convention(witness_method) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %6 |
| %6 = struct_extract %5 : $Int32, #Int32._value // user: %9 |
| %7 = struct_extract %0 : $Int32, #Int32._value // user: %9 |
| %8 = integer_literal $Builtin.Int1, -1 // user: %9 |
| %9 = builtin "sadd_with_overflow_Int32"(%6 : $Builtin.Int32, %7 : $Builtin.Int32, %8 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) // users: %10, %11 |
| %10 = tuple_extract %9 : $(Builtin.Int32, Builtin.Int1), 0 // user: %13 |
| %11 = tuple_extract %9 : $(Builtin.Int32, Builtin.Int1), 1 // user: %12 |
| cond_fail %11 : $Builtin.Int1 // id: %12 |
| %13 = struct $Int32 (%10 : $Builtin.Int32) // user: %15 |
| strong_release %1 : $@box T // id: %14 |
| return %13 : $Int32 // id: %15 |
| } |
| |
| // check that there is a generic specialization of boo |
| // CHECK-LABEL: sil shared [noinline] @_TTSg5V4main1CS0_S_1PS__Sf___TF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_ : $@convention(thin) (C) -> @owned @callee_owned (Int32, @in Float) -> Int32 |
| // CHECK: [[CLOSURE_SPECIALIZATION:%[0-9]+]] = function_ref @_TTSr5V4main1CS0_S_1PS__Sf___TFF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_U_FTS1_Q0__S1_ |
| // CHECK: partial_apply [[CLOSURE_SPECIALIZATION:%[0-9]+]] |
| // CHECK: return |
| |
| // Check that there is a generic specialization of a closure from boo |
| // CHECK-LABEL: sil shared [noinline] @_TTSg5V4main1CS0_S_1PS__Sf___TFF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_U_FTS1_Q0__S1_ |
| // CHECK: return |
| |
| // Check that there is a generic specialization of foo |
| // CHECK-LABEL: sil shared [noinline] @_TTSg5V4main1CS0_S_1PS__S0_S0_S1_S____TF5test43fooUS_1P_S0___FTQ_Q0__FTVs5Int32Sf_S1_ : $@convention(thin) (C, C) -> @owned @callee_owned (Int32, Float) -> Int32 |
| // CHECK: function_ref @_TTSg5V4main1CS0_S_1PS__Sf___TF5test43booUS_1P___FQ_FTVs5Int32Q0__S1_ |
| // check that it invokes a generic specialization of the reabstraction thunk helper which invokes a specialization boo |
| // CHECK: [[THUNK_SPECIALIZATION:%[0-9]+]] = function_ref @_TTSg5V4main1CS0_S_1PS__S0_S0_S1_S____TTRG1_RPq_P5test41P_Pq0_PS0___XFo_dVs5Int32iSf_dS1__XFo_dS1_dSf_dS1__ |
| // CHECK-NOT: apply |
| // CHECK: partial_apply [[THUNK_SPECIALIZATION]] |
| // CHECK-NOT: apply |
| // CHECK: return |
| |
| |
| // Check that there is a generic specialization of gen1 |
| // CHECK-LABEL: sil shared [noinline] @_TTSg5V4main1CS0_S_1PS____TF5test44gen1US_1P__FQ_FVs5Int32S1_ : $@convention(thin) (C) -> @owned @callee_owned (Int32) -> Int32 |
| // check that it invokes a generic specialization of the closure by mean of partial_apply |
| // CHECK: [[CLOSURE_SPECIALIZATION:%[0-9]+]] = function_ref @_TTSg5V4main1CS0_S_1PS____TFF5test44gen1US_1P__FQ_FVs5Int32S1_U_FS1_S1_ |
| // CHECK-NOT: apply |
| // CHECK: partial_apply [[CLOSURE_SPECIALIZATION]] |
| // CHECK-NOT: apply |
| // CHECK: return |
| |
| // Check that there is a generic specialization of a closure from gen1 |
| // CHECK-LABEL: sil shared [noinline] @_TTSg5V4main1CS0_S_1PS____TFF5test44gen1US_1P__FQ_FVs5Int32S1_U_FS1_S1_ : $@convention(thin) (Int32, @owned @box C) -> Int32 |
| // CHECK: return |
| |
| |
| |
| // test4.bar () -> Swift.Int32 |
| // CHECK-LABEL: sil hidden @_TF5test43barFT_Vs5Int32 |
| // check that it does not invoke a generic specialization of foo |
| // CHECK-NOT: function_ref @_TF5test43fooUS_1P_S0___FTQ_Q0__FTVs5Int32Sf_S1_ |
| // check that it invokes a generic specialization of foo |
| // CHECK: function_ref @_TTSg5V4main1CS0_S_1PS__S0_S0_S1_S____TF5test43fooUS_1P_S0___FTQ_Q0__FTVs5Int32Sf_S1_ |
| sil hidden @_TF5test43barFT_Vs5Int32 : $@convention(thin) () -> Int32 { |
| bb0: |
| %0 = alloc_stack $@callee_owned (Int32, Float) -> Int32, var, name "f" // users: %11, %22 |
| // function_ref test4.C.init (test4.C.Type)() -> test4.C |
| %1 = function_ref @_TFV5test41CCfMS0_FT_S0_ : $@convention(thin) (@thin C.Type) -> C // user: %3 |
| %2 = metatype $@thin C.Type // user: %3 |
| %3 = apply %1(%2) : $@convention(thin) (@thin C.Type) -> C // users: %4, %7, %9 |
| debug_value %3 : $C, let, name "c" // id: %4 |
| // function_ref test4.foo <A : test4.P, B : test4.P>(A, B) -> (Swift.Int32, Swift.Float) -> Swift.Int32 |
| %5 = function_ref @_TF5test43fooUS_1P_S0___FTQ_Q0__FTVs5Int32Sf_S1_ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (@in τ_0_0, @in τ_0_1) -> @owned @callee_owned (Int32, Float) -> Int32 // user: %10 |
| %6 = alloc_stack $C // users: %7, %10, %13 |
| store %3 to %6 : $*C // id: %7 |
| %8 = alloc_stack $C // users: %9, %10, %12 |
| store %3 to %8 : $*C // id: %9 |
| %10 = apply %5<C, C>(%6, %8) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (@in τ_0_0, @in τ_0_1) -> @owned @callee_owned (Int32, Float) -> Int32 // users: %11, %14, %20, %21 |
| store %10 to %0 : $*@callee_owned (Int32, Float) -> Int32 // id: %11 |
| dealloc_stack %8 : $*C // id: %12 |
| dealloc_stack %6 : $*C // id: %13 |
| strong_retain %10 : $@callee_owned (Int32, Float) -> Int32 // id: %14 |
| %15 = integer_literal $Builtin.Int32, 3 // user: %16 |
| %16 = struct $Int32 (%15 : $Builtin.Int32) // user: %20 |
| %17 = float_literal $Builtin.FPIEEE80, 0x4000C8F5C28F5C28F5C3 // 3.1400000000000000001 // user: %18 |
| %18 = builtin "fptrunc_FPIEEE80_FPIEEE32"(%17 : $Builtin.FPIEEE80) : $Builtin.FPIEEE32 // user: %19 |
| %19 = struct $Float (%18 : $Builtin.FPIEEE32) // user: %20 |
| %20 = apply %10(%16, %19) : $@callee_owned (Int32, Float) -> Int32 // user: %23 |
| strong_release %10 : $@callee_owned (Int32, Float) -> Int32 // id: %21 |
| dealloc_stack %0 : $*@callee_owned (Int32, Float) -> Int32 // id: %22 |
| return %20 : $Int32 // id: %23 |
| } |
| |
| // test4.testBar () -> Swift.Int32 |
| sil @_TF5test47testBarFT_Vs5Int32 : $@convention(thin) () -> Int32 { |
| bb0: |
| // function_ref test4.bar () -> Swift.Int32 |
| %0 = function_ref @_TF5test43barFT_Vs5Int32 : $@convention(thin) () -> Int32 // user: %1 |
| %1 = apply %0() : $@convention(thin) () -> Int32 // user: %2 |
| return %1 : $Int32 // id: %2 |
| } |
| |
| |
| // CHECK-LABEL: sil @_TF5test48testGen1FT_Vs5Int32 |
| // CHECK: function_ref @_TFV5test41CCfMS0_FT_S0_ |
| // CHECK: apply |
| // Reference to the generic specialization of gen1 |
| // CHECK-NOT: function_ref @_TF5test44gen1US_1P__FQ_FVs5Int32S1_ |
| // CHECK: function_ref @_TTSg5V4main1CS0_S_1PS____TF5test44gen1US_1P__FQ_FVs5Int32S1_ : $@convention(thin) (C) -> @owned @callee_owned (Int32) -> Int32 |
| sil @_TF5test48testGen1FT_Vs5Int32 : $@convention(thin) () -> Int32 { |
| bb0: |
| %0 = alloc_stack $@callee_owned (Int32) -> Int32, var, name "f" // users: %9, %16 |
| // function_ref test4.C.init (test4.C.Type)() -> test4.C |
| %1 = function_ref @_TFV5test41CCfMS0_FT_S0_ : $@convention(thin) (@thin C.Type) -> C // user: %3 |
| %2 = metatype $@thin C.Type // user: %3 |
| %3 = apply %1(%2) : $@convention(thin) (@thin C.Type) -> C // users: %4, %7 |
| debug_value %3 : $C, let, name "c" // id: %4 |
| // function_ref test4.gen1 <A : test4.P>(A) -> (Swift.Int32) -> Swift.Int32 |
| %5 = function_ref @_TF5test44gen1US_1P__FQ_FVs5Int32S1_ : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32) -> Int32 // user: %8 |
| %6 = alloc_stack $C // users: %7, %8, %10 |
| store %3 to %6 : $*C // id: %7 |
| %8 = apply %5<C>(%6) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32) -> Int32 // users: %9, %11, %14, %15 |
| store %8 to %0 : $*@callee_owned (Int32) -> Int32 // id: %9 |
| dealloc_stack %6 : $*C // id: %10 |
| strong_retain %8 : $@callee_owned (Int32) -> Int32 // id: %11 |
| %12 = integer_literal $Builtin.Int32, 3 // user: %13 |
| %13 = struct $Int32 (%12 : $Builtin.Int32) // user: %14 |
| %14 = apply %8(%13) : $@callee_owned (Int32) -> Int32 // user: %17 |
| strong_release %8 : $@callee_owned (Int32) -> Int32 // id: %15 |
| dealloc_stack %0 : $*@callee_owned (Int32) -> Int32 // id: %16 |
| return %14 : $Int32 // id: %17 |
| } |
| |
| // test_bind<A> (Builtin.RawPointer, A.Type) -> () |
| // Check that this is specialized as T=Int. |
| // CHECK-LABEL: sil shared @_TTSg5Si___TF5test9test_bindurFTBpMx_T_ |
| // CHECK: bind_memory %0 : $Builtin.RawPointer, {{%.*}} : $Builtin.Word to $*Int |
| // CHECK: return |
| sil hidden @_TF5test9test_bindurFTBpMx_T_ : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> () { |
| bb0(%0 : $Builtin.RawPointer, %1 : $@thick T.Type): |
| %4 = integer_literal $Builtin.Word, 1 |
| %5 = metatype $@thick T.Type |
| bind_memory %0 : $Builtin.RawPointer, %4 : $Builtin.Word to $*T |
| %7 = tuple () |
| %8 = tuple () |
| return %8 : $() |
| } |
| |
| // Invoke test_bind with T=Int. |
| sil @_TF5test8call_bindFT1pBp_T_ : $@convention(thin) (Builtin.RawPointer) -> () { |
| bb0(%0 : $Builtin.RawPointer): |
| // function_ref test_bind<A> (Builtin.RawPointer, A.Type) -> () |
| %2 = function_ref @_TF5test9test_bindurFTBpMx_T_ : $@convention(thin) <τ_0_0> (Builtin.RawPointer, @thick τ_0_0.Type) -> () |
| %3 = metatype $@thick Int.Type |
| %4 = apply %2<Int>(%0, %3) : $@convention(thin) <τ_0_0> (Builtin.RawPointer, @thick τ_0_0.Type) -> () |
| %5 = tuple () |
| return %5 : $() |
| } |