blob: 8438cffd3759e3adc58bb59583efca3c42ffff56 [file] [log] [blame]
// RUN: %target-sil-opt -enable-sil-verify-all %s -enable-sil-existential-specializer -existential-specializer | %FileCheck %s
// Additional tests for existential_specializer
import Builtin
import Swift
import SwiftShims
internal protocol P {
func foo() -> Int32
}
internal class Klass1 : P {
@inline(never) func foo() -> Int32
init()
}
internal class Klass2 : P {
@inline(never) func foo() -> Int32
init()
}
@inline(never) internal func wrap_foo_ncp(a: inout P, b: inout P) -> Int32
@inline(never) func ncp()
sil hidden [noinline] @$s7dealloc3ncpyyF : $@convention(thin) () -> Int32 {
bb0:
%0 = alloc_stack $P, var, name "magic2"
%1 = alloc_ref $Klass1
%4 = init_existential_addr %0 : $*P, $Klass1
store %1 to %4 : $*Klass1
%6 = alloc_stack $P, var, name "magic3"
%7 = alloc_ref $Klass1
%10 = init_existential_addr %6 : $*P, $Klass1
store %7 to %10 : $*Klass1
%12 = function_ref @$s7dealloc12wrap_foo_ncp1a1bSiAA1P_pz_AaE_pztF : $@convention(thin) (@in P, @in P) -> Int32
%13 = apply %12(%0, %6) : $@convention(thin) (@in P, @in P) -> Int32
debug_value %13 : $Int32, let, name "x"
%14 = alloc_stack $P, var, name "magic4"
%15 = alloc_ref $Klass1
%16 = init_existential_addr %14 : $*P, $Klass1
store %15 to %16 : $*Klass1
%17 = function_ref @$s7dealloc20wrap_foo_ncp_another1aSiAA1P_pz_tF : $@convention(thin) (@inout P) -> Int32
%18 = apply %17(%14) : $@convention(thin) (@inout P) -> Int32
%24 = struct_extract %13 : $Int32, #Int32._value
%25 = struct_extract %18 : $Int32, #Int32._value
%26 = integer_literal $Builtin.Int1, -1
%27 = builtin "sadd_with_overflow_Int32"(%24 : $Builtin.Int32, %25 : $Builtin.Int32, %26 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
%28 = tuple_extract %27 : $(Builtin.Int32, Builtin.Int1), 0
%29 = tuple_extract %27 : $(Builtin.Int32, Builtin.Int1), 1
cond_fail %29 : $Builtin.Int1
%31 = struct $Int32 (%28 : $Builtin.Int32)
destroy_addr %14 : $*P
dealloc_stack %14 : $*P
dealloc_stack %6 : $*P
dealloc_stack %0 : $*P
return %31 : $Int32
}
// CHECK-LABEL: sil public_external [serialized] @$s7dealloc20wrap_foo_ncp_another1aSiAA1P_pz_tF : $@convention(thin) (@inout P) -> Int32 {
// CHECK: bb0(%0 : $*P):
// CHECK: debug_value_addr
// CHECK: alloc_stack
// CHECK: copy_addr
// CHECK: open_existential_addr
// CHECK: witness_method
// CHECK: apply
// CHECK: destroy_addr
// CHECK: dealloc_stack
// CHECK: return
// CHECK-LABEL :} // end sil function '$s7dealloc20wrap_foo_ncp_another1aSiAA1P_pz_tF'
sil public_external [serialized] @$s7dealloc20wrap_foo_ncp_another1aSiAA1P_pz_tF : $@convention(thin) (@inout P) -> Int32 {
bb0(%0 : $*P):
debug_value_addr %0 : $*P, var, name "a", argno 1
%2 = alloc_stack $P
copy_addr %0 to [initialization] %2 : $*P
%4 = open_existential_addr immutable_access %2 : $*P to $*@opened("EE9F89E4-ECF4-11E8-8DDF-D0817AD4059B") P
%5 = witness_method $@opened("EE9F89E4-ECF4-11E8-8DDF-D0817AD4059B") P, #P.foo!1 : <Self where Self : P> (Self) -> () -> Int32, %4 : $*@opened("EE9F89E4-ECF4-11E8-8DDF-D0817AD4059B") P : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32
%6 = apply %5<@opened("EE9F89E4-ECF4-11E8-8DDF-D0817AD4059B") P>(%4) : $@convention(witness_method: P) _0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32
destroy_addr %2 : $*P
dealloc_stack %2 : $*P
return %6 : $Int32
} // end sil function '$s7dealloc20wrap_foo_ncp_another1aSiAA1P_pz_tF'
sil shared [noinline] @$s7dealloc6Klass1C3fooSiyFTf4d_n : $@convention(thin) () -> Int32 {
bb0:
%0 = integer_literal $Builtin.Int32, 10
%1 = struct $Int32 (%0 : $Builtin.Int32)
return %1 : $Int32
}
sil_global hidden [let] @$global_var : $P
// CHECK-LABEL: sil hidden [noinline] @$helper : $@convention(thin) (@in P) -> Int32 {
// CHECK: bb0(%0 : $*P):
// CHECK: debug_value_addr
// CHECK: alloc_stack
// CHECK: copy_addr
// CHECK: destroy_addr
// CHECK: open_existential_addr
// CHECK: witness_method
// CHECK: apply
// CHECK: dealloc_stack
// CHECK: return
// CHECK-LABEL: } // end sil function '$helper'
sil hidden [noinline] @$helper : $@convention(thin) (@in P) -> Int32 {
bb0(%0 : $*P):
debug_value_addr %0 : $*P, var, name "a", argno 1
%4 = alloc_stack $P
copy_addr %0 to [initialization] %4 : $*P
destroy_addr %0 : $*P
%6 = open_existential_addr immutable_access %4 : $*P to $*@opened("3CB58EC4-ECED-11E8-9798-D0817AD4059B") P
%7 = witness_method $@opened("3CB58EC4-ECED-11E8-9798-D0817AD4059B") P, #P.foo!1 : <Self where Self : P> (Self) -> () -> Int32, %6 : $*@opened("3CB58EC4-ECED-11E8-9798-D0817AD4059B") P : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32
%8 = apply %7<@opened("3CB58EC4-ECED-11E8-9798-D0817AD4059B") P>(%6) : $@convention(witness_method: P) _0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32
dealloc_stack %4 : $*P
return %8 : $Int32
}
sil @global_addr_init: $@convention(thin) (Builtin.Int1) -> Int32 {
bb0(%0 : $Builtin.Int1):
alloc_global @$global_var
%1 = global_addr @$global_var : $*P
cond_br %0, bb1, bb2
bb1:
%2 = init_existential_addr %1 : $*P, $Klass1
%3 = alloc_ref $Klass1
store %3 to %2 : $*Klass1
br bb3
bb2:
%5 = init_existential_addr %1 : $*P, $Klass2
%6 = alloc_ref $Klass2
store %6 to %5 : $*Klass2
br bb3
bb3:
%12 = function_ref @$helper : $@convention(thin) (@in P) -> Int32
%13 = apply %12(%1) : $@convention(thin) (@in P) -> Int32
return %13 : $Int32
}
// CHECK-LABEL: sil shared [noinline] @$s7dealloc12wrap_foo_ncp1a1bSiAA1P_pz_AaE_pztFTf4ee_n : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (@in τ_0_0, @in τ_0_1) -> Int32 {
// CHECK: bb0(%0 : $*τ_0_0, %1 : $*τ_0_1):
// CHECK: alloc_stack
// CHECK: init_existential_addr
// CHECK: copy_addr
// CHECK: destroy_addr
// CHECK: alloc_stack
// CHECK: init_existential_addr
// CHECK: copy_addr
// CHECK: destroy_addr
// CHECK: debug_value_addr
// CHECK: debug_value_addr
// CHECK: alloc_stack
// CHECK: copy_addr
// CHECK: destroy_addr
// CHECK: open_existential_addr
// CHECK: witness_method
// CHECK: apply
// CHECK: alloc_stack
// CHECK: copy_addr
// CHECK: destroy_addr
// CHECK: open_existential_addr
// CHECK: witness_method
// CHECK: apply
// CHECK: struct_extract
// CHECK: struct_extract
// CHECK: integer_literal
// CHECK: builtin
// CHECK: tuple_extract
// CHECK: tuple_extract
// CHECK: cond_fail
// CHECK: struct
// CHECK: dealloc_stack
// CHECK: dealloc_stack
// CHECK: dealloc_stack
// CHECK: dealloc_stack
// CHECK: return
// CHECK-LABEL: } // end sil function '$s7dealloc12wrap_foo_ncp1a1bSiAA1P_pz_AaE_pztFTf4ee_n'
sil hidden [noinline] @$s7dealloc12wrap_foo_ncp1a1bSiAA1P_pz_AaE_pztF : $@convention(thin) (@in P, @in P) -> Int32 {
bb0(%0 : $*P, %1 : $*P):
debug_value_addr %0 : $*P, var, name "a", argno 1
debug_value_addr %1 : $*P, var, name "b", argno 2
%4 = alloc_stack $P
copy_addr %0 to [initialization] %4 : $*P
destroy_addr %0 : $*P
%6 = open_existential_addr immutable_access %4 : $*P to $*@opened("3CB58EC4-ECED-11E8-9798-D0817AD4059B") P
%7 = witness_method $@opened("3CB58EC4-ECED-11E8-9798-D0817AD4059B") P, #P.foo!1 : <Self where Self : P> (Self) -> () -> Int32, %6 : $*@opened("3CB58EC4-ECED-11E8-9798-D0817AD4059B") P : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32
%8 = apply %7<@opened("3CB58EC4-ECED-11E8-9798-D0817AD4059B") P>(%6) : $@convention(witness_method: P) _0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32
%9 = alloc_stack $P
copy_addr %1 to [initialization] %9 : $*P
destroy_addr %1 : $*P
%11 = open_existential_addr immutable_access %9 : $*P to $*@opened("3CB58FAA-ECED-11E8-9798-D0817AD4059B") P
%12 = witness_method $@opened("3CB58FAA-ECED-11E8-9798-D0817AD4059B") P, #P.foo!1 : <Self where Self : P> (Self) -> () -> Int32, %11 : $*@opened("3CB58FAA-ECED-11E8-9798-D0817AD4059B") P : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32
%13 = apply %12<@opened("3CB58FAA-ECED-11E8-9798-D0817AD4059B") P>(%11) : $@convention(witness_method: P) _0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32
%14 = struct_extract %8 : $Int32, #Int32._value
%15 = struct_extract %13 : $Int32, #Int32._value
%16 = integer_literal $Builtin.Int1, -1
%17 = builtin "sadd_with_overflow_Int32"(%14 : $Builtin.Int32, %15 : $Builtin.Int32, %16 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1)
%18 = tuple_extract %17 : $(Builtin.Int32, Builtin.Int1), 0
%19 = tuple_extract %17 : $(Builtin.Int32, Builtin.Int1), 1
cond_fail %19 : $Builtin.Int1
%21 = struct $Int32 (%18 : $Builtin.Int32)
dealloc_stack %9 : $*P
dealloc_stack %4 : $*P
return %21 : $Int32
}
sil_witness_table hidden Klass1: P module dealloc {
method #P.foo!1: <Self where Self : P> (Self) -> () -> Int32 : nil
}
sil_witness_table hidden Klass2: P module dealloc {
method #P.foo!1: <Self where Self : P> (Self) -> () -> Int32 : nil
}