blob: 72ff2733e8275426a4b6cca90c1fb0d7dc7674e3 [file] [log] [blame]
// RUN: %target-sil-opt -enable-sil-verify-all %s -sil-combine -inline -sil-combine | FileCheck %s
// Check that type propagation is performed correctly for existentials.
// The concrete type set in init_existential instructions should be propagated
// all the way down to witness_method instructions.
//
// If copy_addr instructions are used to copy one existential into another,
// the information about the concrete type should be still propagated
// correctly through it.
sil_stage canonical
import Builtin
import Swift
import SwiftShims
public protocol ReaderWriterType {
init()
func read(index: Int32) -> Int32
mutating func write(index: Int32, value: Int32)
}
public final class ArrayClassReaderWriter : ReaderWriterType {
@sil_stored private final var elements: [Int32] { get set }
@inline(never) public init()
@inline(never) public final func read(index: Int32) -> Int32
public final func write(index: Int32, value: Int32)
deinit
}
@inline(never) public func readValues() -> Int32
sil_global [fragile] @_swiftEmptyArrayStorage : $_SwiftEmptyArrayStorage
sil [noinline] @_TFC28existential_type_propagation22ArrayClassReaderWritercfMS0_FT_S0_ : $@convention(method) (@owned ArrayClassReaderWriter) -> @owned ArrayClassReaderWriter
sil [noinline] @_TFC28existential_type_propagation22ArrayClassReaderWriterCfMS0_FT_S0_ : $@convention(thin) (@thick ArrayClassReaderWriter.Type) -> @owned ArrayClassReaderWriter
sil [noinline] @_TFC28existential_type_propagation22ArrayClassReaderWriter4readfS0_FSiSi : $@convention(method) (Int32, @guaranteed ArrayClassReaderWriter) -> Int32
sil [transparent] [thunk] @_TTWC28existential_type_propagation22ArrayClassReaderWriterS_16ReaderWriterTypeS_FS1_CuRq_S1__fMq_FT_q_ : $@convention(witness_method) (@out ArrayClassReaderWriter, @thick ArrayClassReaderWriter.Type) -> ()
sil [transparent] [thunk] @_TTWC28existential_type_propagation22ArrayClassReaderWriterS_16ReaderWriterTypeS_FS1_4readuRq_S1__fq_FSiSi : $@convention(witness_method) (Int32, @in_guaranteed ArrayClassReaderWriter) -> Int32
sil [transparent] [thunk] @_TTWC28existential_type_propagation22ArrayClassReaderWriterS_16ReaderWriterTypeS_FS1_5writeuRq_S1__fRq_FTSi5valueSi_T_ : $@convention(witness_method) (Int32, Int32, @inout ArrayClassReaderWriter) -> ()
// CHECK: sil [noinline] @test_existential_type_propagation : $@convention(thin) () -> Int32
// CHECK-NOT: init_existential_addr
// CHECK-NOT: open_existential_addr
// CHECK-NOT: witness_method
// CHECK: function_ref @_TTWC28existential_type_propagation22ArrayClassReaderWriterS_16ReaderWriterTypeS_FS1_4readuRq_S1__fq_FSiSi : $@convention(witness_method) (Int32, @in_guaranteed ArrayClassReaderWriter) -> Int32
// CHECK: return
sil [noinline] @test_existential_type_propagation : $@convention(thin) () -> Int32 {
bb0:
%0 = alloc_stack $Int32
%1 = alloc_stack $ReaderWriterType
// Here we set the concrete type information.
%2 = init_existential_addr %1#1 : $*ReaderWriterType, $ArrayClassReaderWriter
%3 = function_ref @_TFC28existential_type_propagation22ArrayClassReaderWriterCfMS0_FT_S0_ : $@convention(thin) (@thick ArrayClassReaderWriter.Type) -> @owned ArrayClassReaderWriter
%4 = metatype $@thick ArrayClassReaderWriter.Type
%5 = apply %3(%4) : $@convention(thin) (@thick ArrayClassReaderWriter.Type) -> @owned ArrayClassReaderWriter
store %5 to %2 : $*ArrayClassReaderWriter
%7 = open_existential_addr %1#1 : $*ReaderWriterType to $*@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType
// Check that the type information reaches the witness_method instruction and allows for devirtualization.
%8 = witness_method $@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType, #ReaderWriterType.read!1, %7 : $*@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType : $@convention(witness_method) <τ_0_0 where τ_0_0 : ReaderWriterType> (Int32, @in_guaranteed τ_0_0) -> Int32
%9 = integer_literal $Builtin.Int32, 0
%10 = struct $Int32 (%9 : $Builtin.Int32)
%11 = apply %8<@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType>(%10, %7) : $@convention(witness_method) _0_0 where τ_0_0 : ReaderWriterType> (Int32, @in_guaranteed τ_0_0) -> Int32
%12 = integer_literal $Builtin.Int32, 0
%13 = struct $Int32 (%12 : $Builtin.Int32)
store %13 to %0#1 : $*Int32
destroy_addr %1#1 : $*ReaderWriterType
dealloc_stack %1#0 : $*@local_storage ReaderWriterType
dealloc_stack %0#0 : $*@local_storage Int32
return %13 : $Int32
}
// CHECK: sil [noinline] @test_existential_type_propagation_via_copy_addr : $@convention(thin) () -> Int32
// CHECK-NOT: init_existential_addr
// CHECK-NOT: copy_addr
// CHECK-NOT: open_existential_addr
// CHECK-NOT: witness_method
// CHECK: function_ref @_TTWC28existential_type_propagation22ArrayClassReaderWriterS_16ReaderWriterTypeS_FS1_4readuRq_S1__fq_FSiSi : $@convention(witness_method) (Int32, @in_guaranteed ArrayClassReaderWriter) -> Int32
// CHECK: return
sil [noinline] @test_existential_type_propagation_via_copy_addr : $@convention(thin) () -> Int32 {
bb0:
%0 = alloc_stack $Int32
%1 = alloc_stack $ReaderWriterType
%2 = alloc_stack $ReaderWriterType
// Here we set the concrete type information.
%3 = init_existential_addr %1#1 : $*ReaderWriterType, $ArrayClassReaderWriter
%4 = function_ref @_TFC28existential_type_propagation22ArrayClassReaderWriterCfMS0_FT_S0_ : $@convention(thin) (@thick ArrayClassReaderWriter.Type) -> @owned ArrayClassReaderWriter
%5 = metatype $@thick ArrayClassReaderWriter.Type
%6 = apply %4(%5) : $@convention(thin) (@thick ArrayClassReaderWriter.Type) -> @owned ArrayClassReaderWriter
store %6 to %3 : $*ArrayClassReaderWriter
// Check that the type information set for %1 is propagated here to %2.
copy_addr %1#1 to [initialization] %2#1 : $*ReaderWriterType
%9 = open_existential_addr %2#1 : $*ReaderWriterType to $*@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType
// Check that the type information reaches the witness_method instruction and allows for devirtualization.
%10 = witness_method $@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType, #ReaderWriterType.read!1, %9 : $*@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType : $@convention(witness_method) <τ_0_0 where τ_0_0 : ReaderWriterType> (Int32, @in_guaranteed τ_0_0) -> Int32
%11 = integer_literal $Builtin.Int32, 0
%12 = struct $Int32 (%11 : $Builtin.Int32)
%13 = apply %10<@opened("3305E696-5685-11E5-9393-B8E856428C60") ReaderWriterType>(%12, %9) : $@convention(witness_method) _0_0 where τ_0_0 : ReaderWriterType> (Int32, @in_guaranteed τ_0_0) -> Int32
%14 = integer_literal $Builtin.Int32, 0
%15 = struct $Int32 (%14 : $Builtin.Int32)
store %15 to %0#1 : $*Int32
destroy_addr %2#1 : $*ReaderWriterType
dealloc_stack %2#0 : $*@local_storage ReaderWriterType
destroy_addr %1#1 : $*ReaderWriterType
dealloc_stack %1#0 : $*@local_storage ReaderWriterType
dealloc_stack %0#0 : $*@local_storage Int32
return %15 : $Int32
}
sil_vtable ArrayClassReaderWriter {
#ArrayClassReaderWriter.init!initializer.1: _TFC28existential_type_propagation22ArrayClassReaderWritercfMS0_FT_S0_
}
sil_witness_table public_external ArrayClassReaderWriter: ReaderWriterType module main {
method #ReaderWriterType.init!allocator.1: @_TTWC28existential_type_propagation22ArrayClassReaderWriterS_16ReaderWriterTypeS_FS1_CuRq_S1__fMq_FT_q_
method #ReaderWriterType.read!1: @_TTWC28existential_type_propagation22ArrayClassReaderWriterS_16ReaderWriterTypeS_FS1_4readuRq_S1__fq_FSiSi
method #ReaderWriterType.write!1: @_TTWC28existential_type_propagation22ArrayClassReaderWriterS_16ReaderWriterTypeS_FS1_5writeuRq_S1__fRq_FTSi5valueSi_T_
}