mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
It is necessary for opaque values where for casts that will newly start out as checked_cast_brs and be lowered to checked_cast_addr_brs, since the latter has the source formal type, IRGen relies on being able to access it, and there's no way in general to obtain the source formal type from the source lowered type.
414 lines
20 KiB
Plaintext
414 lines
20 KiB
Plaintext
// RUN: %target-sil-opt -ownership-model-eliminator %s | %FileCheck %s
|
|
|
|
sil_stage raw
|
|
|
|
import Builtin
|
|
|
|
sil @use_native_object : $@convention(thin) (@owned Builtin.NativeObject) -> ()
|
|
sil @use_native_object_inguaranteed : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
|
|
sil @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
|
|
|
enum Either<T, R> {
|
|
case left(T)
|
|
case some(R)
|
|
}
|
|
|
|
class C {}
|
|
|
|
struct PairOfInt {
|
|
var lhs : Builtin.Int32
|
|
var rhs : Builtin.Int32
|
|
}
|
|
|
|
// CHECK-LABEL: sil @load : $@convention(thin) (@in Builtin.NativeObject, @in Builtin.Int32) -> () {
|
|
// CHECK: bb0([[ARG1:%[0-9]+]] : $*Builtin.NativeObject, [[ARG2:%[0-9]+]] : $*Builtin.Int32):
|
|
// CHECK: [[LOAD2:%[0-9]+]] = load [[ARG1]] : $*Builtin.NativeObject
|
|
// CHECK: strong_retain [[LOAD2]]
|
|
// CHECK: apply {{%[0-9]+}}([[LOAD2]])
|
|
// CHECK: [[LOAD3:%[0-9]+]] = load [[ARG1]] : $*Builtin.NativeObject
|
|
// CHECK: apply {{%[0-9]+}}([[LOAD3]])
|
|
// CHECK: [[LOAD4:%[0-9]+]] = load [[ARG2]] : $*Builtin.Int32
|
|
// CHECK: apply {{%[0-9]+}}([[LOAD4]])
|
|
sil [ossa] @load : $@convention(thin) (@in Builtin.NativeObject, @in Builtin.Int32) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : $*Builtin.Int32):
|
|
%use_native_object_func = function_ref @use_native_object : $@convention(thin) (@owned Builtin.NativeObject) -> ()
|
|
%use_int32_func = function_ref @use_int32 : $@convention(thin) (Builtin.Int32) -> ()
|
|
|
|
%3 = load [copy] %0 : $*Builtin.NativeObject
|
|
apply %use_native_object_func(%3) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
|
|
|
|
%4 = load [take] %0 : $*Builtin.NativeObject
|
|
apply %use_native_object_func(%4) : $@convention(thin) (@owned Builtin.NativeObject) -> ()
|
|
|
|
%5 = load [trivial] %1 : $*Builtin.Int32
|
|
apply %use_int32_func(%5) : $@convention(thin) (Builtin.Int32) -> ()
|
|
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @store : $@convention(thin) (Builtin.NativeObject, @in Builtin.Int32, Builtin.Int32) -> @out Builtin.NativeObject {
|
|
// CHECK: bb0([[ARG1:%[0-9]+]] : $*Builtin.NativeObject, [[ARG2:%[0-9]+]] : $Builtin.NativeObject, [[ARG3:%[0-9]+]] : $*Builtin.Int32, [[ARG4:%[0-9]+]] : $Builtin.Int32):
|
|
// CHECK: strong_retain [[ARG2]]
|
|
// CHECK: strong_retain [[ARG2]]
|
|
// CHECK: store [[ARG2]] to [[ARG1]] : $*Builtin.NativeObject
|
|
// CHECK: [[OLDVAL:%[0-9]+]] = load [[ARG1]] : $*Builtin.NativeObject
|
|
// CHECK: store [[ARG2]] to [[ARG1]] : $*Builtin.NativeObject
|
|
// CHECK: strong_release [[OLDVAL]]
|
|
// CHECK: store [[ARG4]] to [[ARG3]] : $*Builtin.Int32
|
|
sil [ossa] @store : $@convention(thin) (Builtin.NativeObject, @in Builtin.Int32, Builtin.Int32) -> @out Builtin.NativeObject {
|
|
bb0(%0 : $*Builtin.NativeObject, %1 : @unowned $Builtin.NativeObject, %2 : $*Builtin.Int32, %3 : $Builtin.Int32):
|
|
%4 = copy_value %1 : $Builtin.NativeObject
|
|
%5 = copy_value %1 : $Builtin.NativeObject
|
|
store %4 to [init] %0 : $*Builtin.NativeObject
|
|
store %5 to [assign] %0 : $*Builtin.NativeObject
|
|
store %3 to [trivial] %2 : $*Builtin.Int32
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @borrow : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> () {
|
|
// CHECK: bb0([[ARG:%[0-9]+]] : $*Builtin.NativeObject):
|
|
// CHECK: [[BORROWED_VALUE:%[0-9]+]] = load [[ARG]] : $*Builtin.NativeObject
|
|
// CHECK: unchecked_ref_cast [[BORROWED_VALUE]]
|
|
// CHECK-NOT: end_borrow
|
|
sil [ossa] @borrow : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*Builtin.NativeObject):
|
|
%1 = load_borrow %0 : $*Builtin.NativeObject
|
|
%2 = unchecked_ref_cast %1 : $Builtin.NativeObject to $Builtin.NativeObject
|
|
end_borrow %1 : $Builtin.NativeObject
|
|
%3 = tuple()
|
|
return %3 : $()
|
|
}
|
|
|
|
sil @opaque_function : $@convention(thin) () -> ()
|
|
|
|
// CHECK-LABEL: sil @copy_value_destroy_value : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
// CHECK: bb0([[ARG1:%.*]] : $Builtin.NativeObject):
|
|
// CHECK: strong_retain [[ARG1]]
|
|
// CHECK: strong_release [[ARG1]]
|
|
// CHECK: return [[ARG1]]
|
|
sil [ossa] @copy_value_destroy_value : $@convention(thin) (@owned Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%1 = function_ref @opaque_function : $@convention(thin) () -> ()
|
|
%2 = copy_value %0 : $Builtin.NativeObject
|
|
apply %1() : $@convention(thin) () -> ()
|
|
destroy_value %0 : $Builtin.NativeObject
|
|
return %2 : $Builtin.NativeObject
|
|
}
|
|
|
|
// CHECK-LABEL: sil @begin_borrow_store_borrow : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] : $Builtin.NativeObject):
|
|
// CHECK-NEXT: [[MEM:%.*]] = alloc_stack $Builtin.NativeObject
|
|
// CHECK-NEXT: store [[ARG]] to [[MEM]] : $*Builtin.NativeObject
|
|
// CHECK-NEXT: dealloc_stack [[MEM]] : $*Builtin.NativeObject
|
|
// CHECK-NEXT: strong_release [[ARG]]
|
|
// CHECK-NEXT: tuple ()
|
|
// CHECK-NEXT: return
|
|
// CHECK: } // end sil function 'begin_borrow_store_borrow'
|
|
sil [ossa] @begin_borrow_store_borrow : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
%1 = begin_borrow %0 : $Builtin.NativeObject
|
|
end_borrow %1 : $Builtin.NativeObject
|
|
%2 = alloc_stack $Builtin.NativeObject
|
|
%3 = begin_borrow %0 : $Builtin.NativeObject
|
|
%4 = store_borrow %3 to %2 : $*Builtin.NativeObject
|
|
end_borrow %4 : $*Builtin.NativeObject
|
|
end_borrow %3 : $Builtin.NativeObject
|
|
dealloc_stack %2 : $*Builtin.NativeObject
|
|
destroy_value %0 : $Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// We no longer lower strong_copy_unowned_value. So make sure that we actually don't.
|
|
//
|
|
// CHECK-LABEL: sil @strong_copy_unowned_value_test : $@convention(thin) (@owned @sil_unowned Builtin.NativeObject) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] : $@sil_unowned Builtin.NativeObject):
|
|
// CHECK-NEXT: [[STRONG:%.*]] = strong_copy_unowned_value [[ARG]] : $@sil_unowned Builtin.NativeObject
|
|
// CHECK-NEXT: strong_release [[STRONG]] : $Builtin.NativeObject
|
|
// CHECK-NEXT: unowned_release [[ARG]] : $@sil_unowned Builtin.NativeObject
|
|
// CHECK-NEXT: tuple ()
|
|
// CHECK-NEXT: return
|
|
sil [ossa] @strong_copy_unowned_value_test : $@convention(thin) (@owned @sil_unowned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $@sil_unowned Builtin.NativeObject):
|
|
%1 = strong_copy_unowned_value %0 : $@sil_unowned Builtin.NativeObject
|
|
destroy_value %1 : $Builtin.NativeObject
|
|
destroy_value %0 : $@sil_unowned Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @unmanaged_retain_release_test : $@convention(thin) (@owned Builtin.NativeObject, @owned C) -> () {
|
|
// CHECK: bb0([[ARG1:%.*]] : $Builtin.NativeObject, [[ARG2:%.*]] : $C):
|
|
// CHECK: strong_retain [[ARG1]] : $Builtin.NativeObject
|
|
// CHECK: autorelease_value [[ARG2]] : $C
|
|
// CHECK: strong_release [[ARG1]] : $Builtin.NativeObject
|
|
// CHECK: strong_release [[ARG1]] : $Builtin.NativeObject
|
|
// CHECK: } // end sil function 'unmanaged_retain_release_test'
|
|
sil [ossa] @unmanaged_retain_release_test : $@convention(thin) (@owned Builtin.NativeObject, @owned C) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject, %1 : @owned $C):
|
|
unmanaged_retain_value %0 : $Builtin.NativeObject
|
|
unmanaged_autorelease_value %1 : $C
|
|
br bb1
|
|
|
|
bb1:
|
|
unmanaged_release_value %0 : $Builtin.NativeObject
|
|
destroy_value %0 : $Builtin.NativeObject
|
|
destroy_value %1 : $C
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @checked_cast_br_lowered : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] : $Builtin.NativeObject):
|
|
// CHECK: checked_cast_br Builtin.NativeObject in [[ARG]] : $Builtin.NativeObject to C, [[SUCCBB:bb[0-9]+]], [[FAILBB:bb[0-9]+]]
|
|
//
|
|
// CHECK: [[SUCCBB]]([[CASTED_VALUE:%.*]] : $C):
|
|
// CHECK-NEXT: strong_release [[CASTED_VALUE]]
|
|
// CHECK-NEXT: br bb3
|
|
//
|
|
// CHECK: [[FAILBB]]:
|
|
// CHECK-NEXT: strong_release [[ARG]]
|
|
// CHECK-NEXT: br bb3
|
|
sil [ossa] @checked_cast_br_lowered : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
checked_cast_br Builtin.NativeObject in %0 : $Builtin.NativeObject to C, bb1, bb2
|
|
|
|
bb1(%1 : @owned $C):
|
|
destroy_value %1 : $C
|
|
br bb3
|
|
|
|
bb2(%2 : @owned $Builtin.NativeObject):
|
|
destroy_value %2 : $Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb3:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @end_lifetime_test : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
// CHECK-NOT: end_lifetime {{%.*}} : $Builtin.NativeObject
|
|
sil [ossa] @end_lifetime_test : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : @owned $Builtin.NativeObject):
|
|
end_lifetime %0 : $Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @unchecked_ownership_conversion_test : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
// CHECK: bb0([[ARG:%.*]] : $Builtin.NativeObject):
|
|
// CHECK: return [[ARG]] : $Builtin.NativeObject
|
|
sil [ossa] @unchecked_ownership_conversion_test : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : @guaranteed $Builtin.NativeObject):
|
|
%1 = unchecked_ownership_conversion %0 : $Builtin.NativeObject, @guaranteed to @owned
|
|
return %1 : $Builtin.NativeObject
|
|
}
|
|
|
|
// CHECK-LABEL: sil @switch_enum_default_case : $@convention(thin) (@owned Either<Builtin.NativeObject, AnyObject>) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] : $Either<Builtin.NativeObject, AnyObject>):
|
|
// CHECK: switch_enum [[ARG]] : $Either<Builtin.NativeObject, AnyObject>, case #Either.left!enumelt: [[SUCC_BB:bb[0-9]+]], default [[DEFAULT_BB:bb[0-9]+]]
|
|
//
|
|
// CHECK: [[SUCC_BB]]([[LHS:%.*]] : $Builtin.NativeObject
|
|
// CHECK: strong_release [[LHS]]
|
|
// CHECK: br [[EPILOG_BB:bb[0-9]+]]
|
|
//
|
|
// CHECK: [[DEFAULT_BB]]:
|
|
// CHECK: release_value [[ARG]]
|
|
// CHECK: br [[EPILOG_BB]]
|
|
//
|
|
// CHECK: [[EPILOG_BB]]:
|
|
// CHECK: return
|
|
// CHECK: } // end sil function 'switch_enum_default_case'
|
|
sil [ossa] @switch_enum_default_case : $@convention(thin) (@owned Either<Builtin.NativeObject, Builtin.AnyObject>) -> () {
|
|
bb0(%0 : @owned $Either<Builtin.NativeObject, Builtin.AnyObject>):
|
|
switch_enum %0 : $Either<Builtin.NativeObject, Builtin.AnyObject>, case #Either.left!enumelt: bb1, default bb2
|
|
|
|
bb1(%1 : @owned $Builtin.NativeObject):
|
|
destroy_value %1 : $Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb2(%2 : @owned $Builtin.AnyObject):
|
|
destroy_value %2 : $Builtin.AnyObject
|
|
br bb3
|
|
|
|
bb3:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
class TestArrayStorage {
|
|
@_hasStorage var count: Builtin.Int32
|
|
init()
|
|
}
|
|
|
|
struct TestArray {
|
|
var storage : TestArrayStorage
|
|
}
|
|
|
|
struct TestArray2 {
|
|
var storage : TestArrayStorage
|
|
var someValue : Builtin.Int32
|
|
var storage2 : TestArrayStorage
|
|
}
|
|
|
|
// CHECK-LABEL: sil @test_destructure_struct_tuple : $@convention(thin) (@owned (Builtin.NativeObject, Builtin.Int32), @owned TestArray2) -> @owned (Builtin.NativeObject, Builtin.Int32, TestArrayStorage, Builtin.Int32, TestArrayStorage) {
|
|
// CHECK: bb0([[TUPLE:%.*]] : $(Builtin.NativeObject, Builtin.Int32), [[STRUCT:%.*]] : $TestArray2):
|
|
// CHECK: [[TUP_ELT_0:%.*]] = tuple_extract [[TUPLE]] : $(Builtin.NativeObject, Builtin.Int32), 0
|
|
// CHECK: [[TUP_ELT_1:%.*]] = tuple_extract [[TUPLE]] : $(Builtin.NativeObject, Builtin.Int32), 1
|
|
// CHECK: [[STRUCT_FIELD_0:%.*]] = struct_extract [[STRUCT]] : $TestArray2, #TestArray2.storage
|
|
// CHECK: [[STRUCT_FIELD_1:%.*]] = struct_extract [[STRUCT]] : $TestArray2, #TestArray2.someValue
|
|
// CHECK: [[STRUCT_FIELD_2:%.*]] = struct_extract [[STRUCT]] : $TestArray2, #TestArray2.storage2
|
|
// CHECK: [[RESULT:%.*]] = tuple ([[TUP_ELT_0]] : {{.*}}, [[TUP_ELT_1]] : {{.*}}, [[STRUCT_FIELD_0]] : {{.*}}, [[STRUCT_FIELD_1]] : {{.*}}, [[STRUCT_FIELD_2]] : {{.*}})
|
|
// CHECK: return [[RESULT]]
|
|
// CHECK: } // end sil function 'test_destructure_struct_tuple'
|
|
sil [ossa] @test_destructure_struct_tuple : $@convention(thin) (@owned (Builtin.NativeObject, Builtin.Int32), @owned TestArray2) -> @owned (Builtin.NativeObject, Builtin.Int32, TestArrayStorage, Builtin.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 : $Builtin.Int32, %6 : $TestArrayStorage)
|
|
return %7 : $(Builtin.NativeObject, Builtin.Int32, TestArrayStorage, Builtin.Int32, TestArrayStorage)
|
|
}
|
|
|
|
struct EmptyStruct {}
|
|
|
|
// We should completely eliminate the destructures here since the relevant
|
|
// aggregates are empty.
|
|
//
|
|
// CHECK-LABEL: sil @test_empty_destructure : $@convention(thin) () -> () {
|
|
// CHECK-NOT: destructure_struct
|
|
// CHECK-NOT: destructure_tuple
|
|
// CHECK: } // end sil function 'test_empty_destructure'
|
|
sil [ossa] @test_empty_destructure : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = struct $EmptyStruct()
|
|
() = destructure_struct %0 : $EmptyStruct
|
|
%1 = tuple()
|
|
() = destructure_tuple %1 : $()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [canonical] @test_destructure_struct_tuple_canonical : $@convention(thin) (@owned (Builtin.NativeObject, Builtin.Int32), @owned TestArray2) -> @owned (Builtin.NativeObject, Builtin.Int32, TestArrayStorage, Builtin.Int32, TestArrayStorage) {
|
|
// CHECK: bb0([[TUPLE:%.*]] : $(Builtin.NativeObject, Builtin.Int32), [[STRUCT:%.*]] : $TestArray2):
|
|
// CHECK: [[TUP_ELT_0:%.*]] = tuple_extract [[TUPLE]] : $(Builtin.NativeObject, Builtin.Int32), 0
|
|
// CHECK: [[TUP_ELT_1:%.*]] = tuple_extract [[TUPLE]] : $(Builtin.NativeObject, Builtin.Int32), 1
|
|
// CHECK: [[STRUCT_FIELD_0:%.*]] = struct_extract [[STRUCT]] : $TestArray2, #TestArray2.storage
|
|
// CHECK: [[STRUCT_FIELD_1:%.*]] = struct_extract [[STRUCT]] : $TestArray2, #TestArray2.someValue
|
|
// CHECK: [[STRUCT_FIELD_2:%.*]] = struct_extract [[STRUCT]] : $TestArray2, #TestArray2.storage2
|
|
// CHECK: [[RESULT:%.*]] = tuple ([[TUP_ELT_0]] : {{.*}}, [[TUP_ELT_1]] : {{.*}}, [[STRUCT_FIELD_0]] : {{.*}}, [[STRUCT_FIELD_1]] : {{.*}}, [[STRUCT_FIELD_2]] : {{.*}})
|
|
// CHECK: return [[RESULT]]
|
|
// CHECK: } // end sil function 'test_destructure_struct_tuple_canonical'
|
|
sil [canonical] [ossa] @test_destructure_struct_tuple_canonical : $@convention(thin) (@owned (Builtin.NativeObject, Builtin.Int32), @owned TestArray2) -> @owned (Builtin.NativeObject, Builtin.Int32, TestArrayStorage, Builtin.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 : $Builtin.Int32, %6 : $TestArrayStorage)
|
|
return %7 : $(Builtin.NativeObject, Builtin.Int32, TestArrayStorage, Builtin.Int32, TestArrayStorage)
|
|
}
|
|
|
|
// In the following test, the trivial parts do not have any actual uses... do
|
|
// not emit any value projections for them!
|
|
//
|
|
// CHECK-LABEL: sil [canonical] @test_destructure_with_only_some_uses : $@convention(thin) (@owned (Builtin.NativeObject, Builtin.Int32), @owned TestArray2) -> @owned (Builtin.NativeObject, TestArrayStorage, TestArrayStorage) {
|
|
// CHECK: bb0([[ARG0:%.*]] : $(Builtin.NativeObject, Builtin.Int32), [[ARG1:%.*]] : $TestArray2):
|
|
// CHECK-NEXT: [[ARG0_0:%.*]] = tuple_extract [[ARG0]]
|
|
// CHECK-NEXT: [[STORAGE:%.*]] = struct_extract [[ARG1]] : $TestArray2, #TestArray2.storage
|
|
// CHECK-NEXT: [[STORAGE2:%.*]] = struct_extract [[ARG1]] : $TestArray2, #TestArray2.storage2
|
|
// CHECK-NEXT: [[RESULT:%.*]] = tuple ([[ARG0_0]] : ${{.*}}, [[STORAGE]] : ${{.*}}, [[STORAGE2]] : ${{.*}})
|
|
// CHECK-NEXT: return [[RESULT]]
|
|
// CHECK: } // end sil function 'test_destructure_with_only_some_uses'
|
|
sil [canonical] [ossa] @test_destructure_with_only_some_uses : $@convention(thin) (@owned (Builtin.NativeObject, Builtin.Int32), @owned TestArray2) -> @owned (Builtin.NativeObject, TestArrayStorage, 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, %4 : $TestArrayStorage, %6 : $TestArrayStorage)
|
|
return %7 : $(Builtin.NativeObject, TestArrayStorage, TestArrayStorage)
|
|
}
|
|
|
|
// CHECK-LABEL: sil [canonical] @test_simplify_instruction : $@convention(thin) (@owned Builtin.NativeObject, Builtin.Int32) -> @owned Builtin.NativeObject {
|
|
// CHECK: bb0([[ARG:%.*]] : $Builtin.NativeObject,
|
|
// CHECK: return [[ARG]]
|
|
// CHECK: } // end sil function 'test_simplify_instruction'
|
|
sil [canonical] [ossa] @test_simplify_instruction : $@convention(thin) (@owned Builtin.NativeObject, Builtin.Int32) -> @owned Builtin.NativeObject {
|
|
bb0(%0 : @owned $Builtin.NativeObject, %1 : $Builtin.Int32):
|
|
%2 = tuple(%0 : $Builtin.NativeObject, %1 : $Builtin.Int32)
|
|
(%3, %4) = destructure_tuple %2 : $(Builtin.NativeObject, Builtin.Int32)
|
|
return %3 : $Builtin.NativeObject
|
|
}
|
|
|
|
// Just make sure that we do not crash on this function.
|
|
//
|
|
// CHECK-LABEL: sil @do_not_crash_due_to_debug_value_use : $@convention(thin) (Builtin.Int32, Builtin.Int32) -> () {
|
|
// CHECK: } // end sil function 'do_not_crash_due_to_debug_value_use'
|
|
sil [ossa] @do_not_crash_due_to_debug_value_use : $@convention(thin) (Builtin.Int32, Builtin.Int32) -> () {
|
|
bb0(%0a : $Builtin.Int32, %0b : $Builtin.Int32):
|
|
%0 = tuple(%0a : $Builtin.Int32, %0b : $Builtin.Int32)
|
|
(%1, %2) = destructure_tuple %0 : $(Builtin.Int32, Builtin.Int32)
|
|
debug_value %0 : $(Builtin.Int32, Builtin.Int32), let, name "myName2"
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// Just make sure that we do not crash on this function.
|
|
//
|
|
// CHECK-LABEL: sil @lower_unchecked_value_cast_to_unchecked_bitwise_cast : $@convention(thin) (PairOfInt) -> Builtin.Int64 {
|
|
// CHECK: unchecked_bitwise_cast
|
|
// CHECK: } // end sil function 'lower_unchecked_value_cast_to_unchecked_bitwise_cast'
|
|
sil [ossa] @lower_unchecked_value_cast_to_unchecked_bitwise_cast : $@convention(thin) (PairOfInt) -> Builtin.Int64 {
|
|
bb0(%0a : $PairOfInt):
|
|
%0b = unchecked_value_cast %0a : $PairOfInt to $Builtin.Int64
|
|
return %0b : $Builtin.Int64
|
|
}
|
|
|
|
// Make sure we RAUW the store_borrow's result with its dest while lowering.
|
|
//
|
|
// CHECK-LABEL: sil @lower_store_borrow_result_correctly : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
|
|
// CHECK: bb0([[ARG:%.*]] :
|
|
// CHECK: [[STACK:%.*]] = alloc_stack
|
|
// CHECK: store [[ARG]] to [[STACK]]
|
|
// CHECK: apply {{%.*}}([[STACK]])
|
|
// CHECK: } // end sil function 'lower_store_borrow_result_correctly'
|
|
sil [ossa] @lower_store_borrow_result_correctly : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
|
|
bb0(%0 : @guaranteed $Builtin.NativeObject):
|
|
// This is materializing %0 into memory to be passed as an in_guaranteed arg.
|
|
%1 = alloc_stack $Builtin.NativeObject
|
|
%result = store_borrow %0 to %1 : $*Builtin.NativeObject
|
|
%f = function_ref @use_native_object_inguaranteed : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
|
|
apply %f(%result) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
|
|
end_borrow %result : $*Builtin.NativeObject
|
|
dealloc_stack %1 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil @lower_explicit_copy_addr : $@convention(thin) (@in_guaranteed C) -> () {
|
|
// CHECK: {{[^_]copy_addr}}
|
|
// CHECK: } // end sil function 'lower_explicit_copy_addr'
|
|
sil [ossa] @lower_explicit_copy_addr : $@convention(thin) (@in_guaranteed C) -> () {
|
|
bb0(%0 : $*C):
|
|
%1 = alloc_stack $C
|
|
explicit_copy_addr %0 to [init] %1 : $*C
|
|
destroy_addr %1 : $*C
|
|
dealloc_stack %1 : $*C
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil @closure1: $@convention(thin) (@guaranteed C, @inout_aliasable C) -> ()
|
|
sil @closure2 : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
|
|
|
|
// Ensure no assertion about missing dealloc_stack for partial_apply [on_stack] after OME
|
|
sil [ossa] @test_partial_apply_on_stack: $@convention(thin) (@guaranteed C, @inout C) -> () {
|
|
bb0(%0 : @guaranteed $C, %1 : $*C):
|
|
%f1 = function_ref @closure1: $@convention(thin) (@guaranteed C, @inout_aliasable C) -> ()
|
|
%pa1 = partial_apply [callee_guaranteed] [on_stack] %f1(%0, %1) : $@convention(thin) (@guaranteed C, @inout_aliasable C) -> ()
|
|
%md = mark_dependence %pa1 : $@noescape @callee_guaranteed () -> () on %1 : $*C
|
|
%f2 = function_ref @closure2 : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
|
|
%pa2 = partial_apply [callee_guaranteed] %f2(%md) : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
|
|
destroy_value %pa2 : $@callee_guaranteed () -> ()
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|