// First parse this and then emit a *.sib. Then read in the *.sib, then recreate // RUN: %empty-directory(%t) // RUN: %target-sil-opt -sil-print-types %s -emit-sib -o %t/tmp.sib -module-name borrow // RUN: %target-sil-opt -sil-print-types %t/tmp.sib -o %t/tmp.2.sib -module-name borrow // RUN: %target-sil-opt -sil-print-types %t/tmp.2.sib -module-name borrow -emit-sorted-sil | %FileCheck %s import Builtin import Swift class TestArrayStorage { @_hasStorage var count: Int32 init() } struct TestArray2 { var storage : TestArrayStorage var someValue : Int32 var storage2 : TestArrayStorage } struct Int32 { var x: Builtin.Int32 } struct EmptyStruct {} struct MoveOnlyStruct: ~Copyable { @_hasStorage var i: Int32 deinit } // CHECK-LABEL: sil @async_test : $@convention(thin) @async sil @async_test : $@async () -> () { bb0: %0 = tuple () return %0 : $() } sil [ossa] @strong_copy_unmanaged_value_test : $@convention(thin) (@sil_unmanaged Builtin.NativeObject) -> @owned Builtin.NativeObject { bb0(%0 : $@sil_unmanaged Builtin.NativeObject): %1 = strong_copy_unmanaged_value %0 : $@sil_unmanaged Builtin.NativeObject return %1 : $Builtin.NativeObject } sil [ossa] @test_destructure_struct_tuple : $@convention(thin) (@owned (Builtin.NativeObject, Builtin.Int32), @owned TestArray2) -> @owned (Builtin.NativeObject, Builtin.Int32, TestArrayStorage, Int32, TestArrayStorage) { bb0(%0 : @owned $(Builtin.NativeObject, Builtin.Int32), %1 : @owned $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) } // CHECK-LABEL: sil [ossa] @test_drop_deinit : // CHECK: %1 = drop_deinit %0 : $MoveOnlyStruct // CHECK-LABEL: } // end sil function 'test_drop_deinit' sil [ossa] @test_drop_deinit : $@convention(thin) (@owned MoveOnlyStruct) -> () { bb0(%0 : @owned $MoveOnlyStruct): %1 = drop_deinit %0 : $MoveOnlyStruct destroy_value %1 : $MoveOnlyStruct %3 = tuple () return %3 : $() } sil @test_empty_destructure : $@convention(thin) () -> () { bb0: %0 = struct $EmptyStruct() () = destructure_struct %0 : $EmptyStruct %1 = tuple() () = destructure_tuple %1 : $() return %1 : $() } // CHECK-LABEL: sil [serialized] [ossa] @test_end_lifetime : $@convention(thin) (@owned Builtin.NativeObject) -> () { // CHECK: end_lifetime {{%.*}} : $Builtin.NativeObject sil [serialized] [ossa] @test_end_lifetime : $@convention(thin) (@owned Builtin.NativeObject) -> () { bb0(%0 : @owned $Builtin.NativeObject): end_lifetime %0 : $Builtin.NativeObject return undef : $() } // CHECK-LABEL: sil [lazy_getter] @test_lazy_getter sil [lazy_getter] @test_lazy_getter : $@convention(thin) () -> () { bb0: %0 = tuple () return %0 : $() } // CHECK-LABEL: sil [ossa] @test_movevalue_parsing : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject { // CHECK: bb0([[REGISTER_0:%[^,]+]] : // CHECK-NEXT: [[REGISTER_1:%[^,]+]] = move_value [[REGISTER_0]] // CHECK-NEXT: [[REGISTER_2:%[^,]+]] = move_value [allows_diagnostics] [[REGISTER_1]] // CHECK-NEXT: [[REGISTER_3:%[^,]+]] = move_value [lexical] [[REGISTER_2]] // CHECK-NEXT: [[REGISTER_4:%[^,]+]] = move_value [allows_diagnostics] [lexical] [[REGISTER_3]] // CHECK-NEXT: [[REGISTER_5:%[^,]+]] = move_value [allows_diagnostics] [lexical] [[REGISTER_4]] // CHECK-NEXT: [[REGISTER_6:%[^,]+]] = move_value [var_decl] [[REGISTER_5]] // CHECK-NEXT: return [[REGISTER_6]] // CHECK-NEXT: } // end sil function 'test_movevalue_parsing' sil [ossa] @test_movevalue_parsing : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject { bb0(%0 : @owned $Builtin.NativeObject): %1 = move_value %0 : $Builtin.NativeObject %2 = move_value [allows_diagnostics] %1 : $Builtin.NativeObject %3 = move_value [lexical] %2 : $Builtin.NativeObject %4 = move_value [allows_diagnostics] [lexical] %3 : $Builtin.NativeObject %5 = move_value [lexical] [allows_diagnostics] %4 : $Builtin.NativeObject %6 = move_value [var_decl] %5 : $Builtin.NativeObject return %6 : $Builtin.NativeObject } // CHECK-LABEL: sil [no_allocation] [ossa] @test_no_allocation : $@convention(thin) () -> () { sil [no_allocation] [ossa] @test_no_allocation : $@convention(thin) () -> () { bb0: %1 = tuple () return %1 : $() } // CHECK-LABEL: sil [no_locks] [ossa] @test_no_locks : $@convention(thin) () -> () { sil [no_locks] [ossa] @test_no_locks : $@convention(thin) () -> () { bb0: %1 = tuple () return %1 : $() } // CHECK-LABEL: sil [ossa] @test_pointer_to_address : $@convention(thin) (Builtin.RawPointer, Builtin.Int64) -> () { // CHECK: pointer_to_address %0 : $Builtin.RawPointer to [strict] $*Builtin.Int64 // CHECK: pointer_to_address %0 : $Builtin.RawPointer to [invariant] $*Builtin.Int64 // CHECK: pointer_to_address %0 : $Builtin.RawPointer to [align=1] $*Builtin.Int64 // CHECK: pointer_to_address %0 : $Builtin.RawPointer to [strict] [align=8] $*Builtin.Int64 // CHECK: pointer_to_address %0 : $Builtin.RawPointer to [align=4294967296] $*Builtin.Int64 sil [ossa] @test_pointer_to_address : $@convention(thin) (Builtin.RawPointer, Builtin.Int64) -> () { bb0(%0 : $Builtin.RawPointer, %1 : $Builtin.Int64): %3 = pointer_to_address %0 : $Builtin.RawPointer to $*Builtin.Int64 store %1 to [trivial] %3 : $*Builtin.Int64 %5 = pointer_to_address %0 : $Builtin.RawPointer to [strict] $*Builtin.Int64 store %1 to [trivial] %5 : $*Builtin.Int64 %7 = pointer_to_address %0 : $Builtin.RawPointer to [invariant] $*Builtin.Int64 store %1 to [trivial] %7 : $*Builtin.Int64 %9 = pointer_to_address %0 : $Builtin.RawPointer to [align=1] $*Builtin.Int64 store %1 to [trivial] %9 : $*Builtin.Int64 %11 = pointer_to_address %0 : $Builtin.RawPointer to [strict] [align=8] $*Builtin.Int64 store %1 to [trivial] %11 : $*Builtin.Int64 %13 = pointer_to_address %0 : $Builtin.RawPointer to [align=4294967296] $*Builtin.Int64 store %1 to [trivial] %13 : $*Builtin.Int64 %28 = tuple () return %28 : $() } // CHECK-LABEL: sil [serialized] [ossa] @test_subst_function_type : $@convention(thin) (@guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () for ) -> () sil [serialized] [ossa] @test_subst_function_type : $@convention(thin) (@guaranteed @callee_guaranteed @substituted (@in A, @in B) -> () for ) -> () { entry(%0 : @guaranteed $@callee_guaranteed @substituted (@in C, @in D) -> () for ): return undef : $() } // CHECK-LABEL: sil [serialized] [ossa] @test_subst_function_type_generic_context : $@convention(thin) (@guaranteed @callee_guaranteed @substituted <τ_0_0, τ_0_1> (@in τ_0_0, @in τ_0_1) -> () for ) -> () sil [serialized] [ossa] @test_subst_function_type_generic_context : $@convention(thin) (@guaranteed @callee_guaranteed @substituted (@in A, @in B) -> () for ) -> () { entry(%0 : @guaranteed $@callee_guaranteed @substituted (@in C, @in D) -> () for ): return undef : $() } // CHECK-LABEL: sil [serialized] [ossa] @test_unchecked_ownership_conversion : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () { // CHECK: unchecked_ownership_conversion {{%.*}} : $Builtin.NativeObject, @guaranteed to @owned sil [serialized] [ossa] @test_unchecked_ownership_conversion : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () { bb0(%0 : @guaranteed $Builtin.NativeObject): %1 = unchecked_ownership_conversion %0 : $Builtin.NativeObject, @guaranteed to @owned destroy_value %1 : $Builtin.NativeObject return undef : $() } // CHECK-LABEL: sil @throwError : $@convention(thin) <τ_0_0, τ_0_1> (Builtin.Int64, @in τ_0_0) -> (@out τ_0_1, @error_indirect τ_0_0) // CHECK: copy_addr [take] %3 to [init] %1 : $*τ_0_0 // CHECK: throw %1 : $*τ_0_0 sil @throwError : $@convention(thin) <τ_0_0, τ_0_1> (Builtin.Int64, @in τ_0_0) -> (@error_indirect τ_0_0, @out τ_0_1) { bb0(%0: $*τ_0_1, %1: $*τ_0_0, %2 : $Builtin.Int64, %3 : $*τ_0_0): copy_addr [take] %3 to [init] %1 : $*τ_0_0 throw %1 : $*τ_0_0 } // CHECK: sil @throwError_unowned : $@convention(thin) (Builtin.Int64) -> @error_unowned Builtin.Int64 { // CHECK: bb0(%0 : $Builtin.Int64): // CHECK: throw %0 : $Builtin.Int64 sil @throwError_unowned : $@convention(thin) (Builtin.Int64) -> @error_unowned Builtin.Int64 { bb0(%0 : $Builtin.Int64): throw %0 : $Builtin.Int64 } // CHECK: sil @try_apply : $@convention(thin) (@in T) -> @out V // CHECK: bb0(%0 : $*V, %1 : $*T): // CHECK: %2 = alloc_stack $T // CHECK: %3 = integer_literal $Builtin.Int64, 0 // CHECK: %4 = function_ref @throwError : $@convention(thin) <τ_0_0, τ_0_1> (Builtin.Int64, @in τ_0_0) -> (@out τ_0_1, @error_indirect τ_0_0) // CHECK: try_apply %4(%0, %2, %3, %1) : $@convention(thin) <τ_0_0, τ_0_1> (Builtin.Int64, @in τ_0_0) -> (@out τ_0_1, @error_indirect τ_0_0), normal bb2, error bb1 // CHECK: bb1: // CHECK: destroy_addr %2 : $*T // CHECK: br bb3 // CHECK: bb2(%8 : $()): // CHECK: br bb3 sil @try_apply : $@convention(thin) (@in T) -> @out V { bb0(%0 : $*V, %1: $*T): %2 = alloc_stack $T %3 = integer_literal $Builtin.Int64, 0 %4 = function_ref @throwError : $@convention(thin) (Builtin.Int64, @in T) -> (@error_indirect T, @out V) try_apply %4(%0, %2, %3, %1) : $@convention(thin) (Builtin.Int64, @in T) -> (@error_indirect T, @out V), normal bb1, error bb2 bb1(%5 : $()): br bb3 bb2: destroy_addr %2 : $*T br bb3 bb3: dealloc_stack %2 : $*T %6 = tuple () return %6 : $() }