Files
swift-mirror/test/SIL/Parser/basic.sil
Andrew Trick e50faa5125 [exclusivity] Add 'no_nested_conflict' flag to begin_access.
This statically guarantees that the access has no inner conflict within
its own scope.

IRGen will turn this into a "nontracking" access in which an
exclusivity check is performed for conflicts on an outer scope. However,
unlike normal accesses the runtime does not record the access, and the
access will not be checked for subsequent conflicts.

end_unpaired_access [no_nested_conflict] is not currently
supported. Making a begin_unpaired_access [no_nested_conflict] requires
deleting the corresponding end_unpaired_access. Future runtimes
could support this for verification by storing inline data in the
valud buffer. However, the runtime can never assume that a
[no_nested_conflict] begin_unpaired_access will have a corresponding
end_unpaired_access call without adding a new ExclusivityFlag for
that purpose.
2018-03-27 10:50:07 -07:00

1679 lines
67 KiB
Plaintext

// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=true %s | %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all=true | %FileCheck %s
sil_stage raw // CHECK: sil_stage raw
import Builtin
import Swift
// CHECK: sil_global private @globalinit_token0 : $Builtin.Word
sil_global private @globalinit_token0 : $Builtin.Word
class TestArrayStorage {
@sil_stored var count: Int32
init()
}
struct TestArray {
var storage : TestArrayStorage
}
struct TestArray2 {
var storage : TestArrayStorage
var someValue : Int32
var storage2 : TestArrayStorage
}
// CHECK-LABEL: sil_global @static_array : $TestArrayStorage = {
// CHECK: %initval = object $TestArrayStorage (%3 : $Int32, [tail_elems] %4 : $Int64, %5 : $Int64)
// CHECK-NEXT: }
sil_global @static_array : $TestArrayStorage = {
%0 = integer_literal $Builtin.Int32, 2
%1 = integer_literal $Builtin.Int64, 10
%2 = integer_literal $Builtin.Int64, 20
%3 = struct $Int32 (%0 : $Builtin.Int32)
%4 = struct $Int64 (%1 : $Builtin.Int64)
%5 = struct $Int64 (%2 : $Builtin.Int64)
%initval = object $TestArrayStorage (%3 : $Int32, [tail_elems] %4 : $Int64, %5 : $Int64)
}
// Type references
// Some cyclic type references between SIL function bodies.
class Class1 {
var a : Class2
init()
}
class Class2 {
var b : Class1
init()
}
sil @type_ref1 : $(Class1, Int) -> () // CHECK-LABEL: sil @type_ref1 : $@convention(thin) (Class1, Int)
// Instructions
sil @test1 : $() -> () { // CHECK-LABEL: sil @test1 : $@convention(thin) () -> ()
bb0: // CHECK: bb0:
%0 = tuple () // CHECK: %0 = tuple ()
br bb1 // CHECK: br bb1
bb1:
%b = alloc_box $<τ_0_0> { var τ_0_0 } <Int> // CHECK: %2 = alloc_box $<τ_0_0> { var τ_0_0 } <Int>
%c = integer_literal $Builtin.Word, 1
// CHECK: integer_literal $Builtin.Word, -1
%e = integer_literal $Builtin.Word, -1
return %0 : $() // CHECK: return %0 : $()
}
// Forward referenced values.
sil @test2 : $(Int) -> () { // CHECK-LABEL: sil @test2 : $@convention(thin) (Int) -> ()
bb0(%0 : $Int):
br bb2
bb1:
// Forward reference MRVs.
store %0 to %7 : $*Int // CHECK: store %0 to %7
strong_release %6 : $<τ_0_0> { var τ_0_0 } <Int> // CHECK: strong_release %6
return %5 : $() // CHECK: return %5 : $()
bb2:
%5 = tuple () // CHECK: %5 = tuple ()
%6 = alloc_box $<τ_0_0> { var τ_0_0 } <Int> // CHECK: %6 = alloc_box $<τ_0_0> { var τ_0_0 } <Int>
%7 = project_box %6 : $<τ_0_0> { var τ_0_0 } <Int>, 0 // CHECK: %7 = project_box %6 : $<τ_0_0> { var τ_0_0 } <Int>
br bb1 // CHECK: br bb1
}
sil @named_tuple : $() -> (Builtin.Word, Builtin.Word) {
%0 = integer_literal $Builtin.Word, 42 // CHECK: integer_literal $Builtin.Word, 42
%9 = tuple $(Builtin.Word, Builtin.Word) (%0, %0)
return %9 : $(Builtin.Word, Builtin.Word)
}
sil @return_int : $@convention(thin) (Int) -> Int { // CHECK: $@convention(thin) (Int) -> Int {
bb0(%0 : $Int): // CHECK: bb0(%0 : $Int):
%1 = alloc_stack $Int // CHECK: alloc_stack $Int
store %0 to %1 : $*Int // CHECK: store %0 to %1 : $*Int
%3 = load %1 : $*Int // CHECK: load {{.*}} : $*Int
dealloc_stack %1 : $*Int // CHECK: dealloc_stack {{.*}} : $*Int
return %3 : $Int // CHECK: return {{.*}} : $Int
}
sil @call_fn_pointer : $@convention(thin) (() -> Int) -> Int {
bb0(%0 : $() -> Int):
%1 = alloc_stack $() -> Int // CHECK: alloc_stack $() -> Int
store %0 to %1 : $*() -> Int // CHECK: store %0 to %1 : $*() -> Int
%3 = load %1 : $*() -> Int // CHECK: load %1 : $*() -> Int
strong_retain %3 : $() -> Int // CHECK: strong_retain %3 : $() -> Int
%5 = apply %3() : $() -> Int // CHECK: apply %3() : $() -> Int
%6 = load %1 : $*() -> Int // CHECK: load %1 : $*() -> Int
strong_release %3 : $() -> Int // CHECK: release {{.*}} : $() -> Int
dealloc_stack %1 : $*() -> Int // CHECK: dealloc_stack %1 : $*() -> Int
return %5 : $Int // CHECK: return %5 : $Int
}
sil @return_constant : $@convention(thin) () -> Int { // CHECK-LABEL: @return_constant
bb0: // CHECK: bb0:
// CHECK: function_ref @_TSi25convertFromIntegerLiteralfMSiFT3valBi64__Si : $@convention(thin) (Builtin.Word, @thin Int.Type) -> Int
%1 = function_ref @_TSi25convertFromIntegerLiteralfMSiFT3valBi64__Si : $@convention(thin) (Builtin.Word, @thin Int.Type) -> Int
// CHECK: metatype $@thin Int.Type
%2 = metatype $@thin Int.Type
// CHECK: integer_literal $Builtin.Word, 1
%3 = integer_literal $Builtin.Word, 1
// CHECK: apply
%4 = apply %1(%3, %2) : $@convention(thin) (Builtin.Word, @thin Int.Type) -> Int
// CHECK: return
return %4 : $Int
}
sil @_TSi25convertFromIntegerLiteralfMSiFT3valBi64__Si : $@convention(thin) (Builtin.Word, @thin Int.Type) -> Int
// Parse SIL generated from the following swift program:
// func x(a : Bool) -> Int { if a { return 4 } else {return 5} }
sil @_TSb13getLogicValuefRSbFT_Bi1_ : $@convention(method) (@inout Bool) -> Builtin.Int1
sil @_TSi33_convertFromBuiltinIntegerLiteralfMSiFT3valBi128__Si : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int
// CHECK-LABEL: @_T4test1xFT1aSb_Si
sil @_T4test1xFT1aSb_Si : $@convention(thin) (Bool) -> Int {
// CHECK: bb0(%0 : $Bool):
bb0(%0 : $Bool):
// CHECK: alloc_stack $Bool
%1 = alloc_stack $Bool
// CHECK: store
store %0 to %1 : $*Bool
// CHECK: function_ref @_TSb13getLogicValuefRSbFT_Bi1_ : $@convention(method) (@inout Bool) -> Builtin.Int1
%3 = function_ref @_TSb13getLogicValuefRSbFT_Bi1_ : $@convention(method) (@inout Bool) -> Builtin.Int1
// CHECK: apply
%4 = apply %3(%1) : $@convention(method) (@inout Bool) -> Builtin.Int1
// CHECK: cond_br
cond_br %4, bb1, bb2
// CHECK: bb1:
bb1:
// CHECK: function_ref @_TSi33_convertFromBuiltinIntegerLiteralfMSiFT3valBi128__Si : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int
%6 = function_ref @_TSi33_convertFromBuiltinIntegerLiteralfMSiFT3valBi128__Si : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int
// CHECK: metatype $@thin Int.Type
%7 = metatype $@thin Int.Type
// CHECK: integer_literal $Builtin.Int128, 4
%8 = integer_literal $Builtin.Int128, 4
// CHECK: apply
%9 = apply %6(%8, %7) : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int
// CHECK: dealloc_stack
dealloc_stack %1 : $*Bool
// CHECK: br
br bb3(%9 : $Int)
// CHECK: bb2:
bb2:
// CHECK: function_ref @_TSi33_convertFromBuiltinIntegerLiteralfMSiFT3valBi128__Si : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int
%12 = function_ref @_TSi33_convertFromBuiltinIntegerLiteralfMSiFT3valBi128__Si : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int
// CHECK: metatype $@thin Int.Type
%13 = metatype $@thin Int.Type
// CHECK: integer_literal $Builtin.Int128, 5
%14 = integer_literal $Builtin.Int128, 5
// CHECK: apply
%15 = apply %12(%14, %13) : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int
// CHECK: dealloc_stack
dealloc_stack %1 : $*Bool
// CHECK: br
br bb3(%15 : $Int)
bb3(%17 : $Int):
// CHECK: return
return %17 : $Int
}
protocol P {
func doIt()
}
sil @existentials : $@convention(thin) (@in P) -> () {
bb0(%0 : $*P):
// CHECK: open_existential_addr mutable_access %0
%1 = open_existential_addr mutable_access %0 : $*P to $*@opened("01234567-89ab-cdef-0123-000000000000") P
// CHECK: witness_method ${{.*}}, #P.doIt!1
%2 = witness_method $@opened("01234567-89ab-cdef-0123-000000000000") P, #P.doIt!1, %1 : $*@opened("01234567-89ab-cdef-0123-000000000000") P : $@convention(witness_method: P) <T: P> (@inout T) -> ()
// Make sure we have the correct scope for generic parameters.
// CHECK: witness_method $@opened("{{.*}}") P, #P.doIt!1
%7 = witness_method $@opened("01234567-89ab-cdef-0123-000000000000") P, #P.doIt!1, %1 : $*@opened("01234567-89ab-cdef-0123-000000000000") P : $@convention(witness_method: P) <T: P> (@inout T) -> ()
// CHECK: apply
%3 = apply %2<@opened("01234567-89ab-cdef-0123-000000000000") P>(%1) : $@convention(witness_method: P) <T: P> (@inout T) -> ()
%4 = tuple () // CHECK: tuple ()
// CHECK: open_existential_addr immutable_access
%5 = open_existential_addr immutable_access %0 : $*P to $*@opened("01234567-89ab-cdef-0123-000000000001") P
%6 = witness_method $@opened("01234567-89ab-cdef-0123-000000000001") P, #P.doIt!1, %5 : $*@opened("01234567-89ab-cdef-0123-000000000001") P : $@convention(witness_method: P) <T: P> (@in_guaranteed T) -> ()
%8 = apply %6<@opened("01234567-89ab-cdef-0123-000000000001") P>(%5) : $@convention(witness_method: P) <T: P> (@in_guaranteed T) -> ()
destroy_addr %0 : $*P // CHECK: destroy_addr %0 : $*P
return %4 : $() // CHECK: return
}
class C {
func doIt() {}
}
class D : C {
override func doIt() {
super.doIt()
}
}
sil @classes : $@convention(thin) () -> () {
bb0:
// CHECK: %0 = alloc_ref $C
%C = alloc_ref $C
// CHECK: unchecked_ref_cast %0 : $C to $Builtin.NativeObject
%1 = unchecked_ref_cast %C : $C to $Builtin.NativeObject
// CHECK: unchecked_ref_cast %0 : $C to $Builtin.UnknownObject
%O = unchecked_ref_cast %C : $C to $Builtin.UnknownObject
// CHECK: class_method {{.*}} : $C, #C.doIt!1
%2 = class_method %C : $C, #C.doIt!1 : (C) -> () -> (), $@convention(method) (@guaranteed C) -> ()
// CHECK: alloc_ref $D
%D = alloc_ref $D
// CHECK: upcast {{.*}} : $D to $C
%a = upcast %D : $D to $C
%5 = unconditional_checked_cast %C : $C to $D // CHECK: unconditional_checked_cast
%6 = tuple ()
return %6 : $()
}
sil @optional_upcasts : $@convention(thin) (Optional<D>) -> () {
bb0(%0: $Optional<D>):
// CHECK: upcast {{.*}} : $Optional<D> to $Optional<C>
%1 = upcast %0 : $Optional<D> to $Optional<C>
%2 = tuple ()
return %2 : $()
}
// Generated from:
// func archetype_member_ref<T:Runcible>(x:T) {
// x.free_method()
// T.static_method()
// }
protocol Runcible {
var free:Int { get }
func free_method() -> Int
static func static_method()
}
// CHECK: $@convention(thin) <T where T : Runcible> (@in T) -> ()
sil @_T4arch20archetype_member_refUS_8Runcible___FT1xQ__T_ : $@convention(thin) <T : Runcible> (@in T) -> () {
bb0(%0 : $*T):
// CHECK: witness_method $T, #Runcible.free_method!1
%1 = witness_method $T, #Runcible.free_method!1 : $@convention(witness_method: Runcible) <Self : Runcible> (@in Self) -> Int
%2 = apply %1<T>(%0) : $@convention(witness_method: Runcible) <Self : Runcible> (@in Self) -> Int
%3 = metatype $@thick T.Type
// CHECK: witness_method $T, #Runcible.static_method!1
%4 = witness_method $T, #Runcible.static_method!1 : $@convention(witness_method: Runcible) <Self : Runcible> (@thick T.Type) -> ()
%5 = apply %4<T>(%3) : $@convention(witness_method: Runcible) <Self : Runcible> (@thick T.Type) -> ()
%6 = tuple ()
destroy_addr %0 : $*T
return %6 : $()
}
protocol Bendable { }
// CHECK: $@convention(thin) (@in Bendable & Runcible) -> @out Runcible
sil @_T4todo18erasure_from_protoFT1xPS_8RuncibleS_8Bendable__PS0__ : $@convention(thin) (@in Bendable & Runcible) -> @out Runcible {
bb0(%0 : $*Runcible, %1 : $*Bendable & Runcible):
// CHECK: alloc_box
%2 = alloc_box $<τ_0_0> { var τ_0_0 } <Bendable & Runcible>
%2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <Bendable & Runcible>, 0
// CHECK: copy_addr [take] {{.*}} to [initialization] {{.*}} : $*Bendable & Runcible
copy_addr [take] %1 to [initialization] %2a : $*Bendable & Runcible
// CHECK: alloc_stack
%4 = alloc_stack $Bendable & Runcible
// CHECK: copy_addr {{.*}} to [initialization] {{.*}} : $*Bendable & Runcible
copy_addr %2a to [initialization] %4 : $*Bendable & Runcible
%7 = tuple ()
// CHECK: destroy_addr
destroy_addr %4 : $*Bendable & Runcible
// CHECK: dealloc_stack
dealloc_stack %4 : $*Bendable & Runcible
// CHECK: release
strong_release %2 : $<τ_0_0> { var τ_0_0 } <Bendable & Runcible>
// CHECK: return
return %7 : $()
}
protocol ClassBound : class {
func classBoundMethod()
}
// CHECK: $@convention(thin) (ClassBound) -> ()
sil @_T4todo18class_bound_methodFT1xPS_10ClassBound__T_ : $@convention(thin) (ClassBound) -> () {
bb0(%0 : $ClassBound):
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <ClassBound> // CHECK: alloc_box
%1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <ClassBound>, 0
store %0 to %1a : $*ClassBound // CHECK: store
%3 = load %1a : $*ClassBound // CHECK: load
strong_retain %3 : $ClassBound // CHECK: strong_retain
// CHECK: open_existential_ref {{%.*}} : $ClassBound to $@opened({{.*}}) ClassBound
%5 = open_existential_ref %3 : $ClassBound to $@opened("01234567-89ab-cdef-0123-111111111111") ClassBound
// CHECK: witness_method
%6 = witness_method $@opened("01234567-89ab-cdef-0123-111111111111") ClassBound, #ClassBound.classBoundMethod!1, %5 : $@opened("01234567-89ab-cdef-0123-111111111111") ClassBound : $@convention(witness_method: ClassBound) <T: ClassBound> (T) -> ()
%7 = apply %6<@opened("01234567-89ab-cdef-0123-111111111111") ClassBound>(%5) : $@convention(witness_method: ClassBound) <T: ClassBound> (T) -> ()
%8 = tuple ()
strong_release %1 : $<τ_0_0> { var τ_0_0 } <ClassBound>
return %8 : $()
}
struct Val {
}
// CHECK: $@convention(thin) (@thin Val.Type) -> Val
sil @_TV4todo3ValCfMS0_FT_S0_ : $@convention(thin) (@thin Val.Type) -> Val {
bb0(%0 : $@thin Val.Type):
%1 = alloc_stack $Val // CHECK: alloc_stack
%3 = load %1 : $*Val
dealloc_stack %1 : $*Val
return %3 : $Val
}
class Ref {
}
struct Aleph {
var a:Ref
var b:Val
}
// CHECK: $@convention(thin) (Ref, Val, @thin Aleph.Type) -> Aleph
sil @_TV6struct5AlephCfMS0_FT1aCS_3Ref1bVS_3Val_S0_ : $@convention(thin) (Ref, Val, @thin Aleph.Type) -> Aleph {
bb0(%0 : $Ref, %1 : $Val, %2 : $@thin Aleph.Type):
// CHECK: struct $Aleph ({{%.*}} : $Ref, {{%.*}} : $Val)
%3 = struct $Aleph (%0 : $Ref, %1 : $Val)
return %3 : $Aleph // CHECK: return
}
// CHECK: $@convention(thin) (@thin Aleph.Type) -> Aleph
sil @_TV6struct5AlephCfMS0_FT_S0_ : $@convention(thin) (@thin Aleph.Type) -> Aleph {
bb0(%0 : $@thin Aleph.Type):
%1 = tuple ()
%2 = alloc_box $<τ_0_0> { var τ_0_0 } <Aleph> // CHECK: alloc_box
%2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <Aleph>, 0
// CHECK: struct_element_addr {{.*}} : $*Aleph, #Aleph.a
%5 = struct_element_addr %2a : $*Aleph, #Aleph.a
%6 = load %5 : $*Ref
strong_release %6 : $Ref
%14 = load %2a : $*Aleph
// CHECK: struct_extract {{%.*}} : $Aleph, #Aleph.a
%15 = struct_extract %14 : $Aleph, #Aleph.a
strong_retain %15 : $Ref
strong_release %2 : $<τ_0_0> { var τ_0_0 } <Aleph>
return %14 : $Aleph
}
enum Beth {
case EmptyCase
case DataCase(Int)
}
// CHECK-LABEL: sil @test_union_empty_case : $@convention(thin) () -> Beth {
sil @test_union_empty_case : $() -> Beth {
bb0:
// CHECK: %0 = enum $Beth, #Beth.EmptyCase!enumelt
%0 = enum $Beth, #Beth.EmptyCase!enumelt
return %0 : $Beth
}
// CHECK-LABEL: sil @test_union_data_case : $@convention(thin) (Int) -> Beth {
sil @test_union_data_case : $Int -> Beth {
bb0(%0 : $Int):
// CHECK: %1 = enum $Beth, #Beth.DataCase!enumelt.1, %0 : $Int
%1 = enum $Beth, #Beth.DataCase!enumelt.1, %0 : $Int
return %1 : $Beth
}
protocol Q {}
enum Gimel {
case EmptyCase
case DataCase(Q)
}
sil @test_union_addr_empty_case : $() -> @out Gimel {
bb0(%0 : $*Gimel):
// CHECK: inject_enum_addr {{%.*}} : $*Gimel, #Gimel.EmptyCase!enumelt
inject_enum_addr %0 : $*Gimel, #Gimel.EmptyCase!enumelt
%t = tuple ()
return %t : $()
}
sil @test_union_addr_data_case : $(@in Q) -> (@out Gimel) {
bb0(%0 : $*Gimel, %1 : $*Q):
// CHECK: {{%.*}} = init_enum_data_addr {{%.*}} : $*Gimel, #Gimel.DataCase!enumelt.1
%p = init_enum_data_addr %0 : $*Gimel, #Gimel.DataCase!enumelt.1
copy_addr [take] %1 to [initialization] %p : $*Q
inject_enum_addr %0 : $*Gimel, #Gimel.DataCase!enumelt.1
%t = tuple ()
return %t : $()
}
sil @_T5tuple5floatFT1xSf_T_ : $@convention(thin) (Float32) -> ()
sil @_T5tuple5tupleFT_TSiSf_ : $@convention(thin) () -> (Int, Float32)
// CHECK: $@convention(thin) (Int, Float) -> ()
sil @_T5tuple13tuple_elementFT1xTSiSf__T_ : $@convention(thin) (Int, Float) -> () {
bb0(%0 : $Int, %1 : $Float):
%2 = alloc_box $<τ_0_0> { var τ_0_0 } <(Int, Float)>
%2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <(Int, Float)>, 0
// CHECK: tuple ({{%.*}} : $Int, {{%.*}} : $Float)
%3 = tuple (%0 : $Int, %1 : $Float)
store %3 to %2a : $*(Int, Float)
// CHECK: tuple_element_addr {{%.*}} : $*(Int, Float), 0
%6 = tuple_element_addr %2a : $*(Int, Float), 0
// CHECK: load
%7 = load %6 : $*Int
// CHECK: tuple_element_addr {{%.*}} : $*(Int, Float), 1
%10 = tuple_element_addr %2a : $*(Int, Float), 1
// CHECK: load
%11 = load %10 : $*Float
// CHECK: function_ref
%14 = function_ref @_T5tuple5tupleFT_TSiSf_ : $@convention(thin) () -> (Int, Float)
// CHECK: apply
%15 = apply %14() : $@convention(thin) () -> (Int, Float)
// CHECK: function_ref
%19 = function_ref @_T5tuple5floatFT1xSf_T_ : $@convention(thin) (Float) -> ()
// CHECK: tuple_extract {{%.*}} : $(Int, Float), 1
%17 = tuple_extract %15 : $(Int, Float), 1
// CHECK: apply
%24 = apply %19(%17) : $@convention(thin) (Float) -> ()
%25 = tuple ()
strong_release %2 : $<τ_0_0> { var τ_0_0 } <(Int, Float)>
return %25 : $()
}
class M {
var member: Int
init()
}
// CHECK: $@convention(method) (Int, M) -> ()
sil @_TC3ref1C3foofS0_FT1xSi_T_ : $@convention(method) (Int, M) -> () {
bb0(%0 : $Int, %1 : $M):
%2 = alloc_box $<τ_0_0> { var τ_0_0 } <Int> // CHECK: alloc_box $<τ_0_0> { var τ_0_0 } <Int>
%2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <Int>, 0
store %0 to %2a : $*Int
%4 = alloc_box $<τ_0_0> { var τ_0_0 } <M> // CHECK: alloc_box $<τ_0_0> { var τ_0_0 } <M>
%4a = project_box %4 : $<τ_0_0> { var τ_0_0 } <M>, 0
store %1 to %4a : $*M
%6 = load %2a : $*Int // CHECK: load {{.*}} : $*Int
%7 = load %4a : $*M // CHECK: load {{.*}} : $*M
strong_retain %7 : $M
// CHECK: ref_element_addr {{%.*}} : $M, #M.member
%9 = ref_element_addr %7 : $M, #M.member
store %6 to %9 : $*Int
strong_release %7 : $M
%12 = tuple ()
strong_release %4 : $<τ_0_0> { var τ_0_0 } <M>
strong_release %2 : $<τ_0_0> { var τ_0_0 } <Int>
return %12 : $()
}
class GenericClass<Q> {
var member: Q
init()
}
// CHECK: sil @bound_generic_class_ref_element_addr : $@convention(thin) (GenericClass<Int>) -> Int {
sil @bound_generic_class_ref_element_addr : $@convention(thin) GenericClass<Int> -> Int {
entry(%0 : $GenericClass<Int>):
// CHECK: %1 = ref_element_addr %0 : $GenericClass<Int>, #GenericClass.member
%1 = ref_element_addr %0 : $GenericClass<Int>, #GenericClass.member
// CHECK: %2 = load %1 : $*Int
%2 = load %1 : $*Int
return %2 : $Int
}
class B { }
class E : B { }
// CHECK: $@convention(thin) (B) -> Builtin.Int1
sil @_T4null3isaFT1bCS_1B_Sb : $@convention(thin) (B) -> Builtin.Int1 {
bb0(%0 : $B):
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <B> // CHECK: alloc_box
%1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <B>, 0
store %0 to %1a : $*B
%3 = load %1a : $*B // CHECK: load
strong_retain %3 : $B
checked_cast_br %3 : $B to $E, yes, no // CHECK: checked_cast_br
yes(%5 : $E):
%y = integer_literal $Builtin.Int1, 1
br isa(%y : $Builtin.Int1)
no:
%n = integer_literal $Builtin.Int1, 0
br isa(%n : $Builtin.Int1)
isa(%6 : $Builtin.Int1):
strong_release %3 : $B
strong_release %1 : $<τ_0_0> { var τ_0_0 } <B>
return %6 : $Builtin.Int1
}
sil @_TSd31_convertFromBuiltinFloatLiteralfMSdFT5valueBf64__Sd : $@convention(thin) (Builtin.FPIEEE64, @thin Float64.Type) -> Float64
sil @_TSS32_convertFromBuiltinStringLiteralfMSSFT5valueBp17utf8CodeUnitCountBi64_7isASCIIBi1__SS : $@convention(thin) (Builtin.RawPointer, Builtin.Word, Builtin.Int1, @thin String.Type) -> String
sil @_T5index5gep64FT1pBp1iBi64__Bp : $@convention(thin) (Builtin.RawPointer, Builtin.Word) -> Builtin.RawPointer {
bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.Word):
%2 = alloc_box $<τ_0_0> { var τ_0_0 } <Builtin.RawPointer> // CHECK: alloc_box
%2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <Builtin.RawPointer>, 0
%3 = alloc_box $<τ_0_0> { var τ_0_0 } <Builtin.Word> // CHECK: alloc_box
%3a = project_box %3 : $<τ_0_0> { var τ_0_0 } <Builtin.Word>, 0
store %0 to %2a : $*Builtin.RawPointer
store %1 to %3a : $*Builtin.Word
%7 = load %2a : $*Builtin.RawPointer // CHECK: load
%8 = load %3a : $*Builtin.Word // CHECK: load
// CHECK: index_raw_pointer {{%.*}} : $Builtin.RawPointer, {{%.*}} : $Builtin.Word
%9 = index_raw_pointer %7 : $Builtin.RawPointer, %8 : $Builtin.Word
strong_release %3 : $<τ_0_0> { var τ_0_0 } <Builtin.Word>
strong_release %2 : $<τ_0_0> { var τ_0_0 } <Builtin.RawPointer>
return %9 : $Builtin.RawPointer
}
sil_global @x : $Int
sil @global_callee : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int
// CHECK-LABEL: sil @return_static_array
sil @return_static_array : $@convention(thin) () -> TestArray {
bb0:
// CHECK: %0 = global_value @static_array : $TestArrayStorage
%0 = global_value @static_array : $TestArrayStorage
%1 = struct $TestArray (%0 : $TestArrayStorage)
return %1 : $TestArray
}
// CHECK-LABEL: @global_code : $@convention(thin) () -> ()
sil private @global_code : $() -> () {
bb0:
// CHECK: alloc_global @x
alloc_global @x
// CHECK: global_addr @x : $*Int
%0 = global_addr @x : $*Int
%1 = function_ref @global_callee : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int
%2 = metatype $@thin Int.Type
%3 = integer_literal $Builtin.Int128, 0 // CHECK: integer_literal $Builtin.Int128, 0
%4 = apply %1(%3, %2) : $@convention(thin) (Builtin.Int128, @thin Int.Type) -> Int
store %4 to %0 : $*Int
%6 = tuple ()
return %6 : $()
}
protocol SomeProtocol {
}
class SomeClass : SomeProtocol {
}
class SomeSubclass : SomeClass {}
sil @test_class_metatype : $@convention(thin) (SomeClass, SomeSubclass) -> (@thick SomeClass.Type, @thick SomeClass.Type) {
bb0(%0 : $SomeClass, %1 : $SomeSubclass):
%2 = alloc_box $<τ_0_0> { var τ_0_0 } <SomeClass> // CHECK: alloc_box
%2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <SomeClass>, 0
%3 = alloc_box $<τ_0_0> { var τ_0_0 } <SomeSubclass> // CHECK: alloc_box
%3a = project_box %3 : $<τ_0_0> { var τ_0_0 } <SomeSubclass>, 0
store %0 to %2a : $*SomeClass
store %1 to %3a : $*SomeSubclass
%7 = load %2a : $*SomeClass // CHECK: load
strong_retain %7 : $SomeClass
// CHECK: value_metatype $@thick SomeClass.Type, {{%.*}} : $SomeClass
%9 = value_metatype $@thick SomeClass.Type, %7 : $SomeClass
%11 = load %3a : $*SomeSubclass // CHECK: load
strong_retain %11 : $SomeSubclass
// CHECK: value_metatype $@thick SomeSubclass.Type, {{%.*}} : $SomeSubclass
%13 = value_metatype $@thick SomeSubclass.Type, %11 : $SomeSubclass
%14 = upcast %13 : $@thick SomeSubclass.Type to $@thick SomeClass.Type // CHECK: upcast
%15 = tuple (%9 : $@thick SomeClass.Type, %14 : $@thick SomeClass.Type) // CHECK: tuple
strong_release %11 : $SomeSubclass
strong_release %7 : $SomeClass
strong_release %3 : $<τ_0_0> { var τ_0_0 } <SomeSubclass>
strong_release %2 : $<τ_0_0> { var τ_0_0 } <SomeClass>
return %15 : $(@thick SomeClass.Type, @thick SomeClass.Type)
}
sil @test_value_metatype : $@convention(thin) <T> (@in T) -> (@thick T.Type, @thick T.Type) {
bb0(%0 : $*T):
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <T> // CHECK: alloc_box
%1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <T>, 0
copy_addr [take] %0 to [initialization] %1a : $*T
%3 = metatype $@thick T.Type // CHECK: metatype
%5 = alloc_stack $T // CHECK: alloc_stack
copy_addr %1a to [initialization] %5 : $*T
// CHECK: value_metatype $@thick T.Type, {{%.*}} : $*T
%7 = value_metatype $@thick T.Type, %5 : $*T
%8 = tuple (%3 : $@thick T.Type, %7 : $@thick T.Type) // CHECK: tuple
destroy_addr %5 : $*T
dealloc_stack %5 : $*T
strong_release %1 : $<τ_0_0> { var τ_0_0 } <T>
return %8 : $(@thick T.Type, @thick T.Type)
}
sil @test_existential_metatype : $@convention(thin) (@in SomeProtocol) -> @thick SomeProtocol.Type {
bb0(%0 : $*SomeProtocol):
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <SomeProtocol> // CHECK: alloc_box
%1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <SomeProtocol>, 0
copy_addr [take] %0 to [initialization] %1a : $*SomeProtocol
%4 = alloc_stack $SomeProtocol // CHECK: alloc_stack
copy_addr %1a to [initialization] %4 : $*SomeProtocol
// CHECK: existential_metatype $@thick SomeProtocol.Type, {{%.*}} : $*SomeProtocol
%6 = existential_metatype $@thick SomeProtocol.Type, %4 : $*SomeProtocol
destroy_addr %4 : $*SomeProtocol
dealloc_stack %4 : $*SomeProtocol
strong_release %1 : $<τ_0_0> { var τ_0_0 } <SomeProtocol>
return %6 : $@thick SomeProtocol.Type
}
// CHECK-LABEL: sil @test_unreachable
sil @test_unreachable : $() -> () {
bb0:
unreachable
// CHECK: unreachable
}
sil @test_unowned_retain : $@convention(thin) (SomeClass) -> () {
bb0(%0 : $SomeClass):
%1 = ref_to_unowned %0 : $SomeClass to $@sil_unowned SomeClass
// CHECK: ref_to_unowned %0 : $SomeClass to $@sil_unowned SomeClass
unowned_retain %1 : $@sil_unowned SomeClass
// CHECK: unowned_retain %1 : $@sil_unowned SomeClass
unowned_release %1 : $@sil_unowned SomeClass
// CHECK: unowned_release %1 : $@sil_unowned SomeClass
%4 = unowned_to_ref %1 : $@sil_unowned SomeClass to $SomeClass
// CHECK: unowned_to_ref %1 : $@sil_unowned SomeClass to $SomeClass
%5 = tuple ()
return %5 : $()
}
// CHECK-LABEL: sil @test_basic_block_arguments
sil @test_basic_block_arguments : $@convention(thin) (Builtin.Int1) -> Builtin.Word {
bb0(%0 : $Builtin.Int1):
cond_br %0, bb1, bb2
bb1:
%2 = integer_literal $Builtin.Word, 5
br bb3(%2 : $Builtin.Word)
//CHECK: br bb3(%2 : $Builtin.Word)
bb2:
%4 = integer_literal $Builtin.Word, 6
br bb3(%4 : $Builtin.Word)
//CHECK: br bb3(%4 : $Builtin.Word)
bb3(%6 : $Builtin.Word):
//CHECK: bb3(%6 : $Builtin.Word)
return %6 : $Builtin.Word
}
// CHECK-LABEL: sil @test_cond_branch_basic_block_args
sil @test_cond_branch_basic_block_args : $@convention(thin) (Int, Builtin.Int1) -> Int {
bb0(%0 : $Int, %1 : $Builtin.Int1):
cond_br %1, bb1(%0 : $Int), bb2(%0 : $Int)
// CHECK: cond_br %1, bb1(%0 : $Int), bb2(%0 : $Int)
bb1(%3 : $Int):
br bb3 (%3 : $Int)
bb2(%2 : $Int):
br bb3(%2 : $Int)
bb3(%4 : $Int):
return %4 : $Int
}
// CHECK-LABEL: sil @test_builtin
sil @test_builtin : $@convention(thin) (Builtin.Int1, Builtin.Int1) -> Builtin.Int1 {
bb0(%0 : $Builtin.Int1, %1 : $Builtin.Int1):
%2 = alloc_box $<τ_0_0> { var τ_0_0 } <Builtin.Int1>
%2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <Builtin.Int1>, 0
%3 = alloc_box $<τ_0_0> { var τ_0_0 } <Builtin.Int1>
%3a = project_box %3 : $<τ_0_0> { var τ_0_0 } <Builtin.Int1>, 0
store %0 to %2a : $*Builtin.Int1
store %1 to %3a : $*Builtin.Int1
%8 = load %2a : $*Builtin.Int1
%9 = load %3a : $*Builtin.Int1
// CHECK: builtin "cmp_eq_Int1"({{%.*}} : $Builtin.Int1, {{%.*}} : $Builtin.Int1) : $Builtin.Int1
%10 = builtin "cmp_eq_Int1"(%8 : $Builtin.Int1, %9 : $Builtin.Int1) : $Builtin.Int1
strong_release %3 : $<τ_0_0> { var τ_0_0 } <Builtin.Int1>
strong_release %2 : $<τ_0_0> { var τ_0_0 } <Builtin.Int1>
return %10 : $Builtin.Int1
}
// CHECK-LABEL: sil @test_dealloc_ref
sil @test_dealloc_ref : $@convention(thin) () -> () {
bb0:
%0 = alloc_ref $Class1
dealloc_ref %0 : $Class1
%2 = tuple ()
return %2 : $()
}
// CHECK-LABEL: sil @test_dealloc_partial_ref
sil @test_dealloc_partial_ref : $@convention(thin) () -> () {
bb0:
%0 = alloc_ref $Class1
%1 = metatype $@thick Class1.Type
dealloc_partial_ref %0 : $Class1, %1 : $@thick Class1.Type
%2 = tuple ()
return %2 : $()
}
// CHECK-LABEL: sil @test_dealloc_box
sil @test_dealloc_box : $@convention(thin) () -> () {
bb0:
%0 = alloc_box $<τ_0_0> { var τ_0_0 } <Class1>
dealloc_box %0 : $<τ_0_0> { var τ_0_0 } <Class1>
%2 = tuple ()
return %2 : $()
}
// CHECK-LABEL: sil @test_stack_flag
sil @test_stack_flag : $@convention(thin) () -> () {
bb0:
// CHECK: alloc_ref [stack] $Class1
%0 = alloc_ref [stack] $Class1
// CHECK: dealloc_ref [stack] %0 : $Class1
dealloc_ref [stack] %0 : $Class1
%2 = tuple ()
return %2 : $()
}
// CHECK-LABEL: sil @test_tail_elems
sil @test_tail_elems : $@convention(thin) (Builtin.Word, Builtin.Word) -> () {
bb0(%0 : $Builtin.Word, %1 : $Builtin.Word):
// CHECK: alloc_ref [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * %1 : $Builtin.Word] $Class1
%2 = alloc_ref [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * %1 : $Builtin.Word] $Class1
// CHECK: dealloc_ref %2 : $Class1
dealloc_ref %2 : $Class1
%3 = tuple ()
return %3 : $()
}
// CHECK-LABEL: sil @test_tail_elems_dynamic
sil @test_tail_elems_dynamic : $@convention(thin) (Builtin.Word, Builtin.Word, @thick Class1.Type) -> () {
bb0(%0 : $Builtin.Word, %1 : $Builtin.Word, %2 : $@thick Class1.Type):
// CHECK: alloc_ref_dynamic [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * %1 : $Builtin.Word] %2 : $@thick Class1
%3 = alloc_ref_dynamic [tail_elems $Val * %0 : $Builtin.Word] [tail_elems $Aleph * %1 : $Builtin.Word] %2 : $@thick Class1.Type, $Class1
// CHECK: dealloc_ref %3 : $Class1
dealloc_ref %3 : $Class1
%4 = tuple ()
return %4 : $()
}
// CHECK-LABEL: sil @test_tail_addr
sil @test_tail_addr : $@convention(thin) (@owned Class1, Builtin.Word) -> @owned Class1 {
bb0(%0 : $Class1, %1 : $Builtin.Word):
// CHECK: [[T:%[0-9]+]] = ref_tail_addr %0 : $Class1, $Val
%2 = ref_tail_addr %0 : $Class1, $Val
// CHECK: tail_addr [[T]] : $*Val, %1 : $Builtin.Word, $Aleph
%3 = tail_addr %2 : $*Val, %1 : $Builtin.Word, $Aleph
return %0 : $Class1
}
// CHECK-LABEL: closure_test
sil @takes_closure : $@convention(thin) (@callee_owned () -> ()) -> ()
sil @closure0 : $@convention(thin) (<τ_0_0> { var τ_0_0 } <Int>, @inout Int) -> ()
sil @closure_test : $@convention(thin) () -> () {
bb0:
%0 = alloc_box $<τ_0_0> { var τ_0_0 } <Int> // users: %10, %8, %8, %7, %4
%0a = project_box %0 : $<τ_0_0> { var τ_0_0 } <Int>, 0
%5 = function_ref @takes_closure : $@convention(thin) (@callee_owned () -> ()) -> ()
%6 = function_ref @closure0 : $@convention(thin) (<τ_0_0> { var τ_0_0 } <Int>, @inout Int) -> ()
strong_retain %0 : $<τ_0_0> { var τ_0_0 } <Int>
%8 = partial_apply %6(%0, %0a) : $@convention(thin) (<τ_0_0> { var τ_0_0 } <Int>, @inout Int) -> ()
%9 = apply %5(%8) : $@convention(thin) (@callee_owned () -> ()) -> ()
strong_release %0 : $<τ_0_0> { var τ_0_0 } <Int>
%11 = tuple ()
return %11 : $()
}
sil @test_super_to_archetype_ref : $@convention(thin) <T : Class1> (Class1) -> T {
bb0(%c : $Class1):
%0 = unconditional_checked_cast %c : $Class1 to $T
return %0 : $T
}
sil @test_downcast_archetype_ref : $@convention(thin) <T:Class1, U:Class1> (T) -> () {
bb0(%t : $T):
%0 = unconditional_checked_cast %t : $T to $U
%1 = tuple ()
return %1 : $()
}
protocol ClassP : class {}
enum MaybePair {
case Neither
case Left(Int)
}
sil @_T6switch1aFT_T_ : $@convention(thin) () -> ()
sil @_T6switch1bFT_T_ : $@convention(thin) () -> ()
sil @_T6switch1cFT_T_ : $@convention(thin) () -> ()
// CHECK-LABEL: sil @test_switch_union : $@convention(thin) (MaybePair) -> ()
sil @test_switch_union : $@convention(thin) (MaybePair) -> () {
bb0(%0 : $MaybePair):
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <MaybePair>
%1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <MaybePair>, 0
store %0 to %1a : $*MaybePair
%3 = load %1a : $*MaybePair
%4 = tuple ()
// CHECK: switch_enum %{{.*}} : $MaybePair, case #MaybePair.Neither!enumelt: bb{{.*}}, case #MaybePair.Left!enumelt.1: bb
switch_enum %3 : $MaybePair, case #MaybePair.Neither!enumelt: bb1, case #MaybePair.Left!enumelt.1: bb3
bb1:
br bb2
bb2:
%7 = function_ref @_T6switch1aFT_T_ : $@convention(thin) () -> () // CHECK: function_ref
%8 = apply %7() : $@convention(thin) () -> ()
br bb5 // CHECK: br
bb3(%10 : $Int):
// CHECK: unchecked_enum_data {{%.*}} : $MaybePair, #MaybePair.Left!enumelt.1
%x = unchecked_enum_data %3 : $MaybePair, #MaybePair.Left!enumelt.1
br bb4(%x : $Int)
bb4(%y : $Int):
%12 = function_ref @_T6switch1bFT_T_ : $@convention(thin) () -> () // CHECK: function_ref
%13 = apply %12() : $@convention(thin) () -> ()
br bb5 // CHECK: br
bb5:
%15 = function_ref @_T6switch1cFT_T_ : $@convention(thin) () -> () // CHECK: function_ref
%16 = apply %15() : $@convention(thin) () -> ()
strong_release %1 : $<τ_0_0> { var τ_0_0 } <MaybePair>
%18 = tuple ()
return %18 : $() // CHECK: return
}
enum MaybeAddressOnlyPair {
case Neither
case Left(Q)
}
// CHECK-LABEL: sil @test_switch_union_addr : $@convention(thin) (@in MaybeAddressOnlyPair) -> ()
sil @test_switch_union_addr : $@convention(thin) (@in MaybeAddressOnlyPair) -> () {
bb0(%0 : $*MaybeAddressOnlyPair):
// CHECK: switch_enum_addr [[ENUM:%.*]] : $*MaybeAddressOnlyPair, case #MaybeAddressOnlyPair.Neither!enumelt: bb{{.*}}, case #MaybeAddressOnlyPair.Left!enumelt.1: bb
switch_enum_addr %0 : $*MaybeAddressOnlyPair, case #MaybeAddressOnlyPair.Neither!enumelt: bb1, case #MaybeAddressOnlyPair.Left!enumelt.1: bb2
bb1:
br bb3
bb2:
// CHECK: unchecked_take_enum_data_addr [[ENUM]] : $*MaybeAddressOnlyPair, #MaybeAddressOnlyPair.Left!enumelt.1
%q = unchecked_take_enum_data_addr %0 : $*MaybeAddressOnlyPair, #MaybeAddressOnlyPair.Left!enumelt.1
br bb3
bb3:
%t = tuple ()
return %t : $()
}
// CHECK-LABEL: sil @test_switch_value : $@convention(thin) (Builtin.Word) -> ()
sil @test_switch_value : $@convention(thin) (Builtin.Word) -> () {
bb0(%0 : $Builtin.Word):
// CHECK: switch_value %{{.*}} : $Builtin.Word, case %1: bb1, case %2: bb2
%1 = integer_literal $Builtin.Word, 1
%2 = integer_literal $Builtin.Word, 2
switch_value %0 : $Builtin.Word, case %1: bb1, case %2: bb2
bb1:
%7 = function_ref @_T6switch1aFT_T_ : $@convention(thin) () -> () // CHECK: function_ref
%8 = apply %7() : $@convention(thin) () -> ()
br bb3
bb2:
%12 = function_ref @_T6switch1bFT_T_ : $@convention(thin) () -> () // CHECK: function_ref
%13 = apply %12() : $@convention(thin) () -> ()
br bb3
bb3:
// CHECK: [[FUNC1:%.*]] = function_ref @_T6switch1aFT_T_
// CHECK: [[FUNC2:%.*]] = function_ref @_T6switch1bFT_T_
// CHECK: switch_value %{{.*}} : $@convention(thin) () -> (), case [[FUNC1]]: bb4, case [[FUNC2]]: bb5
%20 = function_ref @_T6switch1bFT_T_ : $@convention(thin) () -> ()
%21 = function_ref @_T6switch1aFT_T_ : $@convention(thin) () -> ()
%22 = function_ref @_T6switch1bFT_T_ : $@convention(thin) () -> ()
switch_value %20 : $@convention(thin) () -> (), case %21: bb4, case %22: bb5
bb4:
// CHECK: function_ref
%37 = function_ref @_T6switch1aFT_T_ : $@convention(thin) () -> ()
%38 = apply %37() : $@convention(thin) () -> ()
br bb6
bb5:
// CHECK: function_ref
%42 = function_ref @_T6switch1bFT_T_ : $@convention(thin) () -> ()
%43 = apply %42() : $@convention(thin) () -> ()
br bb6
bb6:
%18 = tuple ()
// CHECK: return
return %18 : $()
}
// CHECK-LABEL: sil @test_select_value : $@convention(thin) (Builtin.Word) -> Builtin.Word
sil @test_select_value : $@convention(thin) (Builtin.Word) -> Builtin.Word {
bb0(%0 : $Builtin.Word):
%1 = integer_literal $Builtin.Word, 1
%2 = integer_literal $Builtin.Word, 2
%3 = integer_literal $Builtin.Word, 3
%4 = integer_literal $Builtin.Word, 4
%5 = integer_literal $Builtin.Word, 5
%6 = integer_literal $Builtin.Word, 6
%11 = integer_literal $Builtin.Word, 11
%22 = integer_literal $Builtin.Word, 22
%33 = integer_literal $Builtin.Word, 33
%44 = integer_literal $Builtin.Word, 44
%55 = integer_literal $Builtin.Word, 55
%66 = integer_literal $Builtin.Word, 66
// CHECK: select_value %{{.*}} : $Builtin.Word, case %{{.*}}: %{{.*}}, case %{{.*}}: %{{.*}}, case %{{.*}}: %{{.*}}, case %{{.*}}: %{{.*}}, case %{{.*}}: %{{.*}}, default %{{.*}} : $Builtin.Word
%10 = select_value %0: $Builtin.Word, case %1: %11, case %2: %22, case %4: %44, case %5: %55, case %6: %66, default %33 : $Builtin.Word
// CHECK: return
return %10 : $Builtin.Word
}
enum IntEnum : Int {
case E0
case E1
case E2
}
// CHECK-LABEL: sil @test_select_value_with_enum : $@convention(thin) (Builtin.Word) -> Optional<IntEnum>
sil @test_select_value_with_enum : $@convention(thin) (Builtin.Word) -> Optional<IntEnum> {
bb0(%0 : $Builtin.Word):
%1 = integer_literal $Builtin.Word, 0
%2 = integer_literal $Builtin.Word, 1
%3 = enum $IntEnum, #IntEnum.E1!enumelt
%4 = enum $Optional<IntEnum>, #Optional.some!enumelt.1, %3 : $IntEnum
%5 = integer_literal $Builtin.Word, 2
%6 = enum $IntEnum, #IntEnum.E2!enumelt
%7 = enum $Optional<IntEnum>, #Optional.some!enumelt.1, %6 : $IntEnum
%8 = enum $IntEnum, #IntEnum.E0!enumelt
%9 = enum $Optional<IntEnum>, #Optional.some!enumelt.1, %8 : $IntEnum
%10 = enum $Optional<IntEnum>, #Optional.none!enumelt
// CHECK: select_value %{{.*}} : $Builtin.Word, case %{{.*}}: %{{.*}}, case %{{.*}}: %{{.*}}, case %{{.*}}: %{{.*}}, default %{{.*}} : $Optional<IntEnum>
%11 = select_value %0 : $Builtin.Word, case %2: %4, case %5: %7, case %1: %9, default %10 : $Optional<IntEnum>
// CHECK: return
return %11 : $Optional<IntEnum>
}
class ConcreteClass : ClassP {
}
struct Spoon : Bendable {
}
// CHECK-LABEL: sil @test_init_existential : $@convention(thin) (Spoon) -> @out Bendable
sil @test_init_existential : $@convention(thin) (Spoon) -> @out Bendable {
bb0(%0 : $*Bendable, %1 : $Spoon):
%2 = alloc_box $<τ_0_0> { var τ_0_0 } <Spoon>
%2a = project_box %2 : $<τ_0_0> { var τ_0_0 } <Spoon>, 0
store %1 to %2a : $*Spoon
// CHECK: init_existential_addr %{{.*}} : $*Bendable, $Spoon
%4 = init_existential_addr %0 : $*Bendable, $Spoon
// CHECK: deinit_existential_addr %{{.*}} : $*Bendable
deinit_existential_addr %0 : $*Bendable
%5 = load %2a : $*Spoon
store %5 to %4 : $*Spoon
strong_release %2 : $<τ_0_0> { var τ_0_0 } <Spoon>
%8 = tuple ()
return %8 : $()
}
// CHECK-LABEL: sil @test_existential_ref : $@convention(thin) (ConcreteClass) -> ClassP
sil @test_existential_ref : $@convention(thin) (ConcreteClass) -> ClassP {
bb0(%0 : $ConcreteClass):
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <ConcreteClass>
%1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <ConcreteClass>, 0
store %0 to %1a : $*ConcreteClass
%3 = load %1a : $*ConcreteClass
strong_retain %3 : $ConcreteClass
// CHECK: init_existential_ref %{{.*}} : $ConcreteClass : $ConcreteClass, $ClassP
%5 = init_existential_ref %3 : $ConcreteClass : $ConcreteClass, $ClassP
strong_release %1 : $<τ_0_0> { var τ_0_0 } <ConcreteClass>
return %5 : $ClassP
}
sil @test_assign : $(Int, @inout Int) -> () { // CHECK-LABEL: sil @test_assign
bb0(%0 : $Int, %1 : $*Int):
assign %0 to %1 : $*Int // CHECK: assign %0 to %1
unreachable
}
// CHECK-LABEL: sil @test_transparent : $@convention(thin) () -> () {
sil @test_transparent : $@convention(thin) () -> () {
bb0:
%0 = function_ref @classes : $@convention(thin) () -> ()
// CHECK: apply %{{.*}}() : $@convention(thin) () -> ()
%1 = apply %0() : $@convention(thin) () -> ()
%2 = tuple ()
return %2 : $()
}
// CHECK-LABEL: sil [thunk] @test_thunk : $@convention(thin) () -> () {
sil [thunk] @test_thunk : $@convention(thin) () -> () {
bb0:
%0 = tuple ()
return %0 : $()
}
// CHECK-LABEL: sil @takes_unnamed_closure : $@convention(thin) (@callee_owned () -> Int) -> () -> () -> Int
sil @takes_unnamed_closure : $@convention(thin) (@callee_owned () -> Int) -> () -> () -> Int
sil @takes_int64_float32 : $@convention(thin) (Int, Float32) -> ()
// CHECK-LABEL: sil @test_partial_apply : $@convention(thin) (Float) -> @callee_owned (Int) -> () {
sil @test_partial_apply : $@convention(thin) Float -> @callee_owned Int -> () {
bb0(%0 : $Float):
%1 = function_ref @takes_int64_float32 : $@convention(thin) (Int, Float) -> ()
// CHECK: partial_apply %{{.*}}(%{{.*}}) : $@convention(thin) (Int, Float) -> ()
%2 = partial_apply %1(%0) : $@convention(thin) (Int, Float) -> ()
return %2 : $@callee_owned Int -> ()
}
class X {
@objc func f() { }
}
// CHECK-LABEL: sil @test_dynamic_lookup_br : $@convention(thin) (AnyObject) -> ()
sil @test_dynamic_lookup_br : $@convention(thin) (AnyObject) -> () {
bb0(%0 : $AnyObject):
%1 = alloc_box $<τ_0_0> { var τ_0_0 } <AnyObject>
%1a = project_box %1 : $<τ_0_0> { var τ_0_0 } <AnyObject>, 0
store %0 to %1a : $*AnyObject
%3 = alloc_box $<τ_0_0> { var τ_0_0 } <Optional<() -> ()>>
%4 = load %1a : $*AnyObject
strong_retain %4 : $AnyObject
%6 = open_existential_ref %4 : $AnyObject to $@opened("01234567-89ab-cdef-0123-222222222222") AnyObject
%7 = unchecked_ref_cast %6 : $@opened("01234567-89ab-cdef-0123-222222222222") AnyObject to $Builtin.UnknownObject
dynamic_method_br %7 : $Builtin.UnknownObject, #X.f!1.foreign, bb1, bb2
bb1(%z : $@convention(objc_method) (Builtin.UnknownObject) -> ()):
br bb3
bb2:
br bb3
bb3:
%28 = tuple ()
return %28 : $()
}
// CHECK-LABEL: sil @test_mark_fn_escape
sil @test_mark_fn_escape : $() -> () {
%b = alloc_box $<τ_0_0> { var τ_0_0 } <Int>
%ba = project_box %b : $<τ_0_0> { var τ_0_0 } <Int>, 0
%c = alloc_box $<τ_0_0> { var τ_0_0 } <Int>
%ca = project_box %c : $<τ_0_0> { var τ_0_0 } <Int>, 0
// CHECK: mark_function_escape {{.*}} : $*Int
mark_function_escape %ba : $*Int
// CHECK: mark_function_escape {{.*}} : $*Int, {{.*}} : $*Int
mark_function_escape %ba : $*Int, %ca : $*Int
%28 = tuple ()
return %28 : $()
}
// CHECK-LABEL: sil @test_copy_release_value
sil @test_copy_release_value : $(Val) -> (Val) {
bb0(%0 : $Val):
retain_value %0 : $Val
release_value %0 : $Val
return %0 : $Val
// CHECK: retain_value [[T0:%.*]] : $Val
// CHECK-NEXT: release_value [[T0]] : $Val
}
// CHECK-LABEL: sil @test_autorelease_value
sil @test_autorelease_value : $X -> X {
bb0(%0 : $X):
autorelease_value %0 : $X
return %0 : $X
// CHECK: autorelease_value [[T0]] : $X
// CHECK-NEXT: return [[T0]] : $X
}
// CHECK-LABEL: sil @test_set_deallocating
sil @test_set_deallocating : $X -> X {
bb0(%0 : $X):
set_deallocating %0 : $X
return %0 : $X
// CHECK: set_deallocating [[T0]] : $X
// CHECK-NEXT: return [[T0]] : $X
}
struct GenericStruct<T> {
var x : T
}
// CHECK-LABEL: sil @extract_generic_struct
sil @extract_generic_struct : $GenericStruct<Int> -> Int {
entry(%0 : $GenericStruct<Int>):
// CHECK: %1 = struct_extract %0 : $GenericStruct<Int>, #GenericStruct.x
%1 = struct_extract %0 : $GenericStruct<Int>, #GenericStruct.x
// CHECK: return %1 : $Int
return %1 : $Int
}
class Foo {
subscript (x: Int32, y: Int32) -> Int32 { get set }
var x: Int32
var y: Int32
init()
}
sil @Foo_subscript_getter : $@convention(method) (Int32, Int32, @guaranteed Foo) -> Int32 {
bb0(%0 : $Int32, %1 : $Int32, %2 : $Foo):
%3 = tuple ()
%4 = alloc_stack $Int32 // var x // users: %17, %6
%5 = alloc_stack $Int32 // var y // users: %16, %7
store %0 to %4 : $*Int32
store %1 to %5 : $*Int32
%8 = alloc_stack $Foo // var self // users: %15, %14, %9
store %2 to %8 : $*Foo
%10 = metatype $@thin Int32.Type
%12 = integer_literal $Builtin.Int32, 0 // user: %13
%13 = struct $Int32 (%12 : $Builtin.Int32) // user: %18
dealloc_stack %8 : $*Foo
dealloc_stack %5 : $*Int32
dealloc_stack %4 : $*Int32
return %13 : $Int32
}
sil @Foo_subscript_setter : $@convention(method) (Int32, Int32, Int32, @guaranteed Foo) -> () {
bb0(%0 : $Int32, %1 : $Int32, %2 : $Int32, %3 : $Foo):
%4 = alloc_stack $Int32 // var value // users: %16, %5
store %0 to %4 : $*Int32
%6 = alloc_stack $Int32 // var x // users: %15, %8
%7 = alloc_stack $Int32 // var y // users: %14, %9
store %1 to %6 : $*Int32
store %2 to %7 : $*Int32
%10 = alloc_stack $Foo // var self // users: %13, %12, %11
store %3 to %10 : $*Foo
dealloc_stack %10 : $*Foo
dealloc_stack %7 : $*Int32
dealloc_stack %6 : $*Int32
dealloc_stack %4 : $*Int32
%17 = tuple () // user: %18
return %17 : $()
}
// CHECK-LABEL: sil @cond_fail_test : $@convention(thin) (Builtin.Int1) -> () {
sil @cond_fail_test : $Builtin.Int1 -> () {
entry(%0 : $Builtin.Int1):
// CHECK: cond_fail %0 : $Builtin.Int1
cond_fail %0 : $Builtin.Int1
%1 = tuple ()
return %1 : $()
}
sil_global @staticProp: $Int
// CHECK-LABEL: sil private @globalinit_func0 : $@convention(thin) () -> () {
sil private @globalinit_func0 : $@convention(thin) () -> () {
bb0:
%0 = global_addr @staticProp : $*Int
%1 = mark_uninitialized [var] %0 : $*Int
%7 = tuple ()
return %7 : $()
}
// CHECK-LABEL: sil @_TV18lazy_global_access4Type10staticPropSia : $@convention(thin) () -> Builtin.RawPointer {
sil @_TV18lazy_global_access4Type10staticPropSia : $@convention(thin) () -> Builtin.RawPointer {
bb0:
// CHECK: global_addr @globalinit_token0 : $*Builtin.Word
%1 = global_addr @globalinit_token0 : $*Builtin.Word
// CHECK: unchecked_addr_cast {{%.*}} : $*Builtin.Word to $*Builtin.RawPointer
%a = unchecked_addr_cast %1 : $*Builtin.Word to $*Builtin.RawPointer
%2 = address_to_pointer %a : $*Builtin.RawPointer to $Builtin.RawPointer
%3 = function_ref @globalinit_func0 : $@convention(thin) () -> ()
// CHECK: {{%.*}} = builtin "once"({{%.*}} : $Builtin.RawPointer, {{%.*}} : $@convention(thin) () -> ()) : $()
%5 = builtin "once"(%2 : $Builtin.RawPointer, %3 : $@convention(thin) () -> ()) : $()
%6 = global_addr @staticProp : $*Int
%7 = address_to_pointer %6 : $*Int to $Builtin.RawPointer
return %7 : $Builtin.RawPointer
}
// CHECK-LABEL: sil @thin_metatype : $@convention(thin) (@thin Int.Type) -> @thick Int.Type
sil @thin_metatype : $@convention(thin) (@thin Int.Type) -> @thick Int.Type
sil @undef_value : $() -> () {
bb0:
store undef to undef : $*Builtin.Int1
unreachable
}
// CHECK-LABEL: sil @debug_value
sil @debug_value : $@convention(thin) (Int, @in P) -> () {
bb0(%0 : $Int, %1 : $*P):
debug_value %0 : $Int // CHECK: debug_value %0 : $Int
debug_value_addr %1 : $*P // CHECK: debug_value_addr %1 : $*P
unreachable
}
// CHECK-LABEL: sil @block_storage_type
sil @block_storage_type : $@convention(thin) Int -> @convention(block) () -> () {
entry(%0 : $Int):
// CHECK: [[STORAGE:%.*]] = alloc_stack $@block_storage Int
%s = alloc_stack $@block_storage Int
// CHECK: [[PROJECT:%.*]] = project_block_storage [[STORAGE]] : $*@block_storage Int
%c = project_block_storage %s : $*@block_storage Int
// CHECK: store %0 to [[PROJECT]]
store %0 to %c : $*Int
// CHECK: [[FUNC:%.*]] = function_ref
%f = function_ref @block_invoke : $@convention(c) (@inout_aliasable @block_storage Int) -> ()
// CHECK: [[BLOCK:%.*]] = init_block_storage_header [[STORAGE]] : $*@block_storage Int, invoke [[FUNC]] : $@convention(c) (@inout_aliasable @block_storage Int) -> (), type $@convention(block) () -> ()
%b = init_block_storage_header %s : $*@block_storage Int, invoke %f : $@convention(c) (@inout_aliasable @block_storage Int) -> (), type $@convention(block) () -> ()
// CHECK: dealloc_stack [[STORAGE]] : $*@block_storage Int
dealloc_stack %s : $*@block_storage Int
// CHECK: return [[BLOCK]] : $@convention(block) () -> ()
return %b : $@convention(block) () -> ()
}
sil @block_invoke : $@convention(c) (@inout_aliasable @block_storage Int) -> () {
entry(%0 : $*@block_storage Int):
return undef : $()
}
// CHECK-LABEL: sil @bitcasts : $@convention(thin) (@owned Class1) -> @owned (Class2, Int) {
// CHECK: bb0(%0 : $Class1):
// CHECK-NEXT: %1 = unchecked_ref_cast %0 : $Class1 to $Class2
// CHECK-NEXT: %2 = unchecked_trivial_bit_cast %0 : $Class1 to $Int
// CHECK-NEXT: %3 = tuple (%1 : $Class2, %2 : $Int)
// CHECK-NEXT: return %3 : $(Class2, Int)
sil @bitcasts : $@convention(thin) (@owned Class1) -> @owned (Class2, Int) {
entry(%0 : $Class1):
%1 = unchecked_ref_cast %0 : $Class1 to $Class2
%2 = unchecked_trivial_bit_cast %0 : $Class1 to $Int
%3 = tuple (%1 : $Class2, %2 : $Int)
return %3 : $(Class2, Int)
}
// CHECK-LABEL: sil @bridge_object : $@convention(thin) (@owned Class1, Builtin.Word) -> () {
// CHECK: bb0([[X:%.*]] : $Class1, [[W:%.*]] : $Builtin.Word):
// CHECK-NEXT: [[A:%.*]] = ref_to_bridge_object [[X]] : $Class1, [[W]] : $Builtin.Word
// CHECK-NEXT: [[B:%.*]] = bridge_object_to_ref [[A]] : $Builtin.BridgeObject to $Class1
// CHECK-NEXT: [[C:%.*]] = bridge_object_to_word [[A]] : $Builtin.BridgeObject to $Builtin.Word
// CHECK-NEXT: return undef : $()
sil @bridge_object : $@convention(thin) (@owned Class1, Builtin.Word) -> () {
entry(%x : $Class1, %w : $Builtin.Word):
%a = ref_to_bridge_object %x : $Class1, %w : $Builtin.Word
%b = bridge_object_to_ref %a : $Builtin.BridgeObject to $Class1
%c = bridge_object_to_word %a : $Builtin.BridgeObject to $Builtin.Word
return undef : $()
}
// CHECK-LABEL: sil [_semantics "foo"] @test_semantics : $@convention(thin) () -> () {
sil [_semantics "foo"] @test_semantics : $@convention(thin) () -> () {
bb0:
%0 = tuple ()
return %0 : $()
}
// CHECK-LABEL: sil shared_external @test_shared_external_definition : $@convention(thin) () -> () {
sil shared_external @test_shared_external_definition : $@convention(thin) () -> () {
bb0:
%0 = tuple ()
return %0 : $()
}
// CHECK-LABEL: sil @select_enum : $@convention(thin) (@in Beth) -> () {
sil @select_enum : $@convention(thin) (@in Beth) -> () {
bb0(%0 : $*Beth):
%1 = load %0 : $*Beth
%2 = integer_literal $Builtin.Int32, 2
%3 = integer_literal $Builtin.Int32, 3
// CHECK: %4 = select_enum %1 : $Beth, case #Beth.EmptyCase!enumelt: %2, case #Beth.DataCase!enumelt.1: %3 : $Builtin.Int32
%4 = select_enum %1 : $Beth, case #Beth.EmptyCase!enumelt: %2, case #Beth.DataCase!enumelt.1: %3 : $Builtin.Int32
// CHECK: %5 = select_enum_addr %0 : $*Beth, case #Beth.EmptyCase!enumelt: %2, case #Beth.DataCase!enumelt.1: %3 : $Builtin.Int32
%5 = select_enum_addr %0 : $*Beth, case #Beth.EmptyCase!enumelt: %2, case #Beth.DataCase!enumelt.1: %3 : $Builtin.Int32
// CHECK: %6 = select_enum %1 : $Beth, case #Beth.EmptyCase!enumelt: %2, default %3 : $Builtin.Int32
%6 = select_enum %1 : $Beth, case #Beth.EmptyCase!enumelt: %2, default %3 : $Builtin.Int32
// CHECK: %7 = select_enum_addr %0 : $*Beth, case #Beth.EmptyCase!enumelt: %2, default %3 : $Builtin.Int32
%7 = select_enum_addr %0 : $*Beth, case #Beth.EmptyCase!enumelt: %2, default %3 : $Builtin.Int32
return undef : $()
}
struct SomeError: Error {
var _domain: String { get }
var _code: Int { get }
}
// CHECK-LABEL: sil @existential_box : $@convention(thin) (SomeError) -> () {
sil @existential_box : $@convention(thin) (SomeError) -> () {
bb0(%0 : $SomeError):
// CHECK: %1 = alloc_existential_box $Error, $SomeError
%1 = alloc_existential_box $Error, $SomeError
// CHECK: %2 = project_existential_box $SomeError in %1 : $Error
%2 = project_existential_box $SomeError in %1 : $Error
// CHECK: store %0 to %2 : $*SomeError
store %0 to %2 : $*SomeError
// CHECK: %4 = open_existential_box %1 : $Error to $*@opened("01234567-89AB-CDEF-0123-333333333333") Error
%4 = open_existential_box %1 : $Error to $*@opened("01234567-89AB-CDEF-0123-333333333333") Error
// CHECK: destroy_addr %4 : $*@opened("01234567-89AB-CDEF-0123-333333333333") Error
destroy_addr %4 : $*@opened("01234567-89AB-CDEF-0123-333333333333") Error
// CHECK: dealloc_existential_box %1 : $Error, $SomeError
dealloc_existential_box %1 : $Error, $SomeError
return undef : $()
}
sil @convert_function : $@convention(thin) (@convention(thin) (AnyObject) -> Optional<AnyObject>) -> (@convention(thin) (Optional<AnyObject>) -> AnyObject) {
entry(%0 : $@convention(thin) (AnyObject) -> Optional<AnyObject>):
%1 = convert_function %0 : $@convention(thin) (AnyObject) -> Optional<AnyObject> to $@convention(thin) (Optional<AnyObject>) -> AnyObject
return %1 : $@convention(thin) (Optional<AnyObject>) -> AnyObject
}
// CHECK-LABEL: sil @convert_function_trivial
// CHECK: %1 = convert_escape_to_noescape %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
// CHECK: return
sil @convert_function_trivial : $@convention(thin) (@owned @callee_guaranteed (AnyObject) -> Optional<AnyObject>) -> () {
entry(%0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject>):
%1 = convert_escape_to_noescape %0 : $@callee_guaranteed (AnyObject) -> Optional<AnyObject> to $@noescape @callee_guaranteed (Optional<AnyObject>) -> AnyObject
return undef : $()
}
sil @meta_metatype : $@convention(thin) () -> @thick Beth.Type.Type {
entry:
%m = metatype $@thick Beth.Type.Type
return %m : $@thick Beth.Type.Type
}
sil @concrete_meta_existential_metatype : $@convention(thin) () -> @thick P.Type.Protocol {
entry:
%m = metatype $@thick P.Type.Protocol
return %m : $@thick P.Type.Protocol
}
sil @concrete_meta_existential_meta_existential_metatype
: $@convention(thin) () -> @thick P.Type.Type.Protocol {
entry:
%m = metatype $@thick P.Type.Type.Protocol
return %m : $@thick P.Type.Type.Protocol
}
sil @function_metatype : $@convention(thin) () -> @thick (() -> ()).Type {
entry:
%m = metatype $@thick (() -> ()).Type
return %m : $@thick (() -> ()).Type
}
// CHECK-LABEL: sil @error_result : $@convention(thin) () -> @error Error
sil @error_result : $@convention(thin) () -> @error Error {
entry:
unreachable
}
// CHECK-LABEL: sil @error_result2 : $@convention(thin) () -> (Int, @error Error)
sil @error_result2 : $@convention(thin) () -> (Int, @error Error) {
entry:
unreachable
}
// CHECK-LABEL: sil @error_result3 : $@convention(thin) () -> (@owned Class1, @error Error)
sil @error_result3 : $@convention(thin) () -> (@owned Class1, @error Error) {
entry:
unreachable
}
// CHECK-LABEL: sil @error_result4 : $@convention(thin) (@owned Class1) -> (@owned Class1, @error Error)
sil @error_result4 : $@convention(thin) (@owned Class1) -> (@owned Class1, @error Error) {
entry(%0 : $Class1):
return %0 : $Class1
}
// CHECK-LABEL: sil @try_apply : $@convention(thin) (@owned Class1) -> ()
sil @try_apply : $@convention(thin) (@owned Class1) -> () {
entry(%0 : $Class1):
%1 = function_ref @error_result4 : $@convention(thin) (@owned Class1) -> (@owned Class1, @error Error)
// CHECK: try_apply %1(%0) : $@convention(thin) (@owned Class1) -> (@owned Class1, @error Error), normal bb1, error bb2
try_apply %1(%0) : $@convention(thin) (@owned Class1) -> (@owned Class1, @error Error),
normal bb1, error bb2
bb1(%2 : $Class1):
strong_release %2 : $Class1
br bb3
bb2(%3 : $Error):
release_value %3 : $Error
br bb3
bb3:
%4 = tuple ()
return %4 : $()
}
// CHECK-LABEL: sil @apply_nothrow : $@convention(thin) (@owned Class1) -> ()
sil @apply_nothrow : $@convention(thin) (@owned Class1) -> () {
entry(%0 : $Class1):
%1 = function_ref @error_result4 : $@convention(thin) (@owned Class1) -> (@owned Class1, @error Error)
// CHECK: apply [nothrow] %1(%0) : $@convention(thin) (@owned Class1) -> (@owned Class1, @error Error)
%2 = apply [nothrow] %1(%0) : $@convention(thin) (@owned Class1) -> (@owned Class1, @error Error)
strong_release %2 : $Class1
%3 = tuple ()
return %3 : $()
}
struct Fork : Bendable {}
sil @thin_convention : $@convention(thin) () -> ()
sil @c_convention : $@convention(c) () -> ()
sil @method_convention : $@convention(method) (Int) -> ()
sil @objc_method_convention : $@convention(objc_method) (Int) -> ()
sil @witness_method_convention : $@convention(witness_method: Bendable) (Fork) -> ()
// CHECK-LABEL: sil @conventions : $@convention(thin) (() -> (), @convention(thin) () -> (), @convention(c) () -> (), @convention(block) () -> (), @convention(method) () -> (), @convention(objc_method) () -> (), @convention(witness_method: Bendable) (Fork) -> ()) -> () {
sil @conventions : $@convention(thin) (@convention(thick) () -> (),
@convention(thin) () -> (),
@convention(c) () -> (),
@convention(block) () -> (),
@convention(method) () -> (),
@convention(objc_method) () -> (),
@convention(witness_method: Bendable) (Fork) -> ()) -> () {
entry(%0 : $@convention(thick) () -> (),
%1 : $@convention(thin) () -> (),
%2 : $@convention(c) () -> (),
%3 : $@convention(block) () -> (),
%4 : $@convention(method) () -> (),
%5 : $@convention(objc_method) () -> (),
%6 : $@convention(witness_method: Bendable) (Fork) -> ()):
return undef : $()
}
// CHECK-LABEL: sil @is_unique : $@convention(thin) (@inout Builtin.NativeObject)
sil @is_unique : $@convention(thin) (@inout Builtin.NativeObject) -> Builtin.Int1 {
bb0(%0 : $*Builtin.NativeObject):
// CHECK: %1 = is_unique %0 : $*Builtin.NativeObject
%1 = is_unique %0 : $*Builtin.NativeObject
return %1 : $Builtin.Int1
}
// CHECK-LABEL: sil @is_unique_or_pinned : $@convention(thin) (@inout Builtin.NativeObject)
sil @is_unique_or_pinned : $@convention(thin) (@inout Builtin.NativeObject) -> Builtin.Int1 {
bb0(%0 : $*Builtin.NativeObject):
// CHECK: %1 = is_unique_or_pinned %0 : $*Builtin.NativeObject
%1 = is_unique_or_pinned %0 : $*Builtin.NativeObject
return %1 : $Builtin.Int1
}
// CHECK-LABEL: sil @is_escaping_closure
sil @is_escaping_closure : $@convention(thin)(@guaranteed @callee_guaranteed () -> ()) -> Builtin.Int1 {
bb0(%0 : $@callee_guaranteed () -> ()):
// CHECK: %1 = is_escaping_closure %0 : $@callee_guaranteed () -> ()
%1 = is_escaping_closure %0: $@callee_guaranteed () -> ()
return %1 : $Builtin.Int1
}
// CHECK-LABEL: sil @box_type : $@convention(thin) (<τ_0_0> { var τ_0_0 } <Int>, Int) -> () {
sil @box_type : $@convention(thin) (<τ_0_0> { var τ_0_0 } <Int>, Int) -> () {
// CHECK: bb0(%0 : $<τ_0_0> { var τ_0_0 } <Int>, %1 : $Int):
bb0(%0 : $<τ_0_0> { var τ_0_0 } <Int>, %1 : $Int):
// CHECK-NEXT: strong_retain %0 : $<τ_0_0> { var τ_0_0 } <Int>
strong_retain %0 : $<τ_0_0> { var τ_0_0 } <Int>
// CHECK-NEXT: %3 = project_box %0 : $<τ_0_0> { var τ_0_0 } <Int>, 0
%3 = project_box %0 : $<τ_0_0> { var τ_0_0 } <Int>, 0
// CHECK-NEXT: store %1 to %3 : $*Int
store %1 to %3 : $*Int
// CHECK-NEXT: strong_release %0 : $<τ_0_0> { var τ_0_0 } <Int>
strong_release %0 : $<τ_0_0> { var τ_0_0 } <Int>
return undef : $()
}
// CHECK-LABEL: sil @value_names : $@convention(thin) (Builtin.Int1) -> () {
sil @value_names : $@convention(thin) (Builtin.Int1) -> () {
// CHECK: bb0(%0 : $Builtin.Int1):
entry(%param : $Builtin.Int1):
// CHECK-NEXT: %1 = tuple ()
%v_o_i_d = tuple ()
// CHECK-NEXT: cond_br %0, bb1, bb2
cond_br %param, then, else
// CHECK: bb1:
then:
// CHECK-NEXT: %3 = tuple ()
%void2 = tuple ()
// CHECK-NEXT: br bb2
br else
// CHECK: bb2:
else:
// CHECK-NEXT: %5 = tuple ()
%3void = tuple ()
// CHECK-NEXT: return %5 : $()
return %3void : $()
}
// CHECK: } // end sil function 'value_names'
class Resource {}
struct Value { var x: Resource }
struct Storage { var y: Resource }
class ParentClass { var storage: Storage; init() }
struct ParentStruct { var storage: Storage }
sil @init_storage : $@convention(thin) (@owned Value) -> @owned Storage
sil @init_storage_indirect : $@convention(thin) (@owned Value) -> @out Storage
sil @set_class_property : $@convention(thin) (@owned Value, @guaranteed ParentClass) -> ()
sil @set_struct_property : $@convention(thin) (@owned Value, @inout ParentStruct) -> ()
sil @init_storage_generic : $@convention(thin) <T, U> (@in T) -> @out U
sil @set_class_property_generic : $@convention(thin) <V, W: AnyObject> (@in V, @guaranteed W) -> ()
sil @mutate_value : $@convention(thin) (@inout Value) -> ()
// CHECK-LABEL: sil @mark_uninitialized_behavior
sil @mark_uninitialized_behavior : $@convention(thin) (@owned ParentClass, @inout ParentStruct) -> () {
entry(%a : $ParentClass, %b : $*ParentStruct):
// CHECK: [[INIT_STORAGE:%.*]] = function_ref @init_storage
%c = function_ref @init_storage : $@convention(thin) (@owned Value) -> @owned Storage
// CHECK: [[SET_CLASS_PROP:%.*]] = function_ref @set_class_property
%d = function_ref @set_class_property : $@convention(thin) (@owned Value, @guaranteed ParentClass) -> ()
// CHECK: [[CLASS_STORAGE:%.*]] = ref_element_addr [[CLASS_SELF:%.*]] :
%e = ref_element_addr %a : $ParentClass, #ParentClass.storage
// CHECK: mark_uninitialized_behavior [[INIT_STORAGE]]([[CLASS_STORAGE]]) : $@convention(thin) (@owned Value) -> @owned Storage, [[SET_CLASS_PROP]]([[CLASS_SELF]]) : $@convention(thin) (@owned Value, @guaranteed ParentClass) -> ()
%f = mark_uninitialized_behavior %c(%e) : $@convention(thin) (@owned Value) -> @owned Storage,
%d(%a) : $@convention(thin) (@owned Value, @guaranteed ParentClass) -> ()
%g = function_ref @mutate_value : $@convention(thin) (@inout Value) -> ()
apply %g(%f) : $@convention(thin) (@inout Value) -> ()
// CHECK: [[INIT_STORAGE:%.*]] = function_ref @init_storage_indirect
%h = function_ref @init_storage_indirect : $@convention(thin) (@owned Value) -> @out Storage
// CHECK: [[SET_PROP:%.*]] = function_ref @set_struct_property
%i = function_ref @set_struct_property : $@convention(thin) (@owned Value, @inout ParentStruct) -> ()
// CHECK: [[STORAGE:%.*]] = struct_element_addr [[SELF:%.*]] :
%j = struct_element_addr %b : $*ParentStruct, #ParentStruct.storage
// CHECK: mark_uninitialized_behavior [[INIT_STORAGE]]([[STORAGE]]) : $@convention(thin) (@owned Value) -> @out Storage, [[SET_PROP]]([[SELF]]) : $@convention(thin) (@owned Value, @inout ParentStruct) -> ()
%k = mark_uninitialized_behavior %h(%j) : $@convention(thin) (@owned Value) -> @out Storage,
%i(%b) : $@convention(thin) (@owned Value, @inout ParentStruct) -> ()
// CHECK: [[INIT_STORAGE:%.*]] = function_ref @init_storage_generic
%l = function_ref @init_storage_generic : $@convention(thin) <T, U> (@in T) -> @out U
// CHECK: [[SET_PROP:%.*]] = function_ref @set_class_property_generic
%m = function_ref @set_class_property_generic : $@convention(thin) <V, W: AnyObject> (@in V, @guaranteed W) -> ()
// CHECK: mark_uninitialized_behavior [[INIT_STORAGE]]<Value, Storage>([[CLASS_STORAGE]]) : $@convention(thin) <τ_0_0, τ_0_1> (@in τ_0_0) -> @out τ_0_1, [[SET_PROP]]<Value, ParentClass>([[CLASS_SELF]]) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 : AnyObject> (@in τ_0_0, @guaranteed τ_0_1) -> ()
%n = mark_uninitialized_behavior %l<Value, Storage>(%e) : $@convention(thin) <T, U> (@in T) -> @out U,
%m<Value, ParentClass>(%a) : $@convention(thin) <V, W: AnyObject> (@in V, @guaranteed W) -> ()
unreachable
}
// CHECK-LABEL: sil @test_pointer_to_address
sil @test_pointer_to_address : $(Builtin.RawPointer, X) -> () {
bb0(%0 : $Builtin.RawPointer, %1 : $X):
%2 = pointer_to_address %0 : $Builtin.RawPointer to $*X
store %1 to %2 : $*X
// CHECK: [[T2:%.*]] = pointer_to_address {{%.*}} : $Builtin.RawPointer to $*X
// CHECK-NEXT: store %1 to [[T2]] : $*X
%3 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*X
store %1 to %3 : $*X
// CHECK: [[T3:%.*]] = pointer_to_address {{%.*}} : $Builtin.RawPointer to [strict] $*X
// CHECK-NEXT: store %1 to [[T3]] : $*X
%28 = tuple ()
return %28 : $()
}
// CHECK-LABEL: sil @test_bind_memory
sil @test_bind_memory : $(Builtin.RawPointer, Builtin.Word) -> () {
bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.Word):
bind_memory %0 : $Builtin.RawPointer, %1 : $Builtin.Word to $*X
// CHECK: bind_memory {{%.*}} : $Builtin.RawPointer, {{%.*}} : $Builtin.Word to $*X
%28 = tuple ()
return %28 : $()
}
// CHECK-LABEL: sil @test_end_lifetime : $@convention(thin) (@owned Builtin.NativeObject) -> () {
// CHECK: end_lifetime {{%.*}} : $Builtin.NativeObject
sil @test_end_lifetime : $@convention(thin) (@owned Builtin.NativeObject) -> () {
bb0(%0 : $Builtin.NativeObject):
end_lifetime %0 : $Builtin.NativeObject
return undef : $()
}
// CHECK-LABEL: sil @test_unchecked_ownership_conversion : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
// CHECK: unchecked_ownership_conversion {{%.*}} : $Builtin.NativeObject, @guaranteed to @owned
sil @test_unchecked_ownership_conversion : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
bb0(%0 : $Builtin.NativeObject):
%1 = unchecked_ownership_conversion %0 : $Builtin.NativeObject, @guaranteed to @owned
return undef : $()
}
sil @test_destructure_struct_tuple : $@convention(thin) (@owned (Builtin.NativeObject, Builtin.Int32), @owned TestArray2) -> @owned (Builtin.NativeObject, Builtin.Int32, TestArrayStorage, Int32, TestArrayStorage) {
bb0(%0 : $(Builtin.NativeObject, Builtin.Int32), %1 : $TestArray2):
(%2, %3) = destructure_tuple %0 : $(Builtin.NativeObject, Builtin.Int32)
(%4, %5, %6) = destructure_struct %1 : $TestArray2
%7 = tuple(%2 : $Builtin.NativeObject, %3 : $Builtin.Int32, %4 : $TestArrayStorage, %5 : $Int32, %6 : $TestArrayStorage)
return %7 : $(Builtin.NativeObject, Builtin.Int32, TestArrayStorage, Int32, TestArrayStorage)
}
class A {
@sil_stored var property: Any { get set }
deinit
init()
}
// CHECK-LABEL: sil @test_access : $@convention(thin) (@guaranteed A) -> () {
// CHECK: begin_access [read] [dynamic]
// CHECK: begin_access [read] [dynamic] [no_nested_conflict]
// CHECK: begin_unpaired_access [read] [dynamic]
// CHECK: begin_unpaired_access [read] [dynamic] [no_nested_conflict]
// CHECK-LABEL: } // end sil function 'test_access'
sil @test_access : $(@guaranteed A) -> () {
bb0(%0 : $A):
%1 = alloc_stack $Any
%2 = ref_element_addr %0 : $A, #A.property
%3 = begin_access [dynamic] [read] %2 : $*Any
copy_addr %3 to [initialization] %1 : $*Any
end_access %3 : $*Any
%6 = begin_access [read] [dynamic] [no_nested_conflict] %2 : $*Any
copy_addr %6 to %1 : $*Any
end_access %6 : $*Any
%9 = alloc_stack $Builtin.UnsafeValueBuffer
begin_unpaired_access [read] [dynamic] %2 : $*Any, %9 : $*Builtin.UnsafeValueBuffer
copy_addr %2 to %1 : $*Any
end_unpaired_access [dynamic] %9 : $*Builtin.UnsafeValueBuffer
begin_unpaired_access [read] [dynamic] [no_nested_conflict] %2 : $*Any, %9 : $*Builtin.UnsafeValueBuffer
copy_addr %2 to %1 : $*Any
destroy_addr %1 : $*Any
dealloc_stack %9 : $*Builtin.UnsafeValueBuffer
dealloc_stack %1 : $*Any
%20 = tuple ()
return %20 : $()
}
struct EmptyStruct {}
sil @test_empty_destructure : $@convention(thin) () -> () {
bb0:
%0 = struct $EmptyStruct()
() = destructure_struct %0 : $EmptyStruct
%1 = tuple()
() = destructure_tuple %1 : $()
return %1 : $()
}
// CHECK-LABEL: sil_vtable Foo {
// CHECK: #Foo.subscript!getter.1: {{.*}} : hidden @Foo_subscript_getter
// CHECK: #Foo.subscript!setter.1: {{.*}} : @Foo_subscript_setter
// CHECK: }
sil_vtable Foo {
// Override the linkage to check if it is parsed correctly.
#Foo.subscript!getter.1: hidden @Foo_subscript_getter
// The public linkage is the same as the function's linkage and should not be printed.
#Foo.subscript!setter.1: public @Foo_subscript_setter
}