1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
// RUN: %target-sil-opt -enforce-exclusivity=none -enable-sil-verify-all %s -sil-combine -devirtualizer | %FileCheck %s
// Test to see if concrete type can be propagated from
// global_addr in sil_combiner.
sil_stage canonical
import Builtin
import Swift
protocol SomeProtocol {
func foo() -> Int
}
class SomeClass : SomeProtocol {
init()
func foo() -> Int
}
sil hidden [thunk] [always_inline] @foo_ : $@convention(witness_method:SomeProtocol) (@in_guaranteed SomeClass) -> Int {
bb0(%0 : $*SomeClass):
%1 = load %0 : $*SomeClass
%2 = class_method %1 : $SomeClass, #SomeClass.foo : (SomeClass) -> () -> Int, $@convention(method) (@guaranteed SomeClass) -> Int
%3 = apply %2(%1) : $@convention(method) (@guaranteed SomeClass) -> Int
return %3 : $Int
}
sil hidden_external @foo : $@convention(method) (@guaranteed SomeClass) -> Int
sil_global hidden [let] @$global_var : $SomeProtocol
// CHECK-LABEL: sil @witness_global_addr
// CHECK: bb0
// CHECK: alloc_global
// CHECK: global_addr
// CHECK: init_existential_addr
// CHECK: alloc_ref
// CHECK: store
// CHECK: function_ref
// CHECK: apply
// CHECK: return
// CHECK: } // end sil function 'witness_global_addr'
sil @witness_global_addr : $@convention(thin) () -> Int {
bb0:
alloc_global @$global_var
%3 = global_addr @$global_var : $*SomeProtocol
%4 = init_existential_addr %3 : $*SomeProtocol, $SomeClass
%5 = alloc_ref $SomeClass
store %5 to %4 : $*SomeClass
%8 = alloc_stack $SomeProtocol
copy_addr %3 to [init] %8 : $*SomeProtocol
%9 = open_existential_addr immutable_access %8 : $*SomeProtocol to $*@opened("1B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self
%10 = witness_method $@opened("1B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self, #SomeProtocol.foo : <Self where Self : SomeProtocol> (Self) -> () -> Int, %9 : $*@opened("1B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self : $@convention(witness_method: SomeProtocol) <τ_0_0 where τ_0_0 : SomeProtocol> (@in_guaranteed τ_0_0) -> Int
%11 = apply %10<@opened("1B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self>(%9) : $@convention(witness_method: SomeProtocol) <τ_0_0 where τ_0_0 : SomeProtocol> (@in_guaranteed τ_0_0) -> Int
destroy_addr %8 : $*SomeProtocol
dealloc_stack %8 : $*SomeProtocol
return %11 : $Int
}
// CHECK-LABEL: sil @witness_global_addr_fail_1
// CHECK: bb0
// CHECK: alloc_global
// CHECK: global_addr
// CHECK: bb1
// CHECK: bb2
// CHECK: bb3
// CHECK: alloc_ref
// CHECK: store
// CHECK: alloc_stack
// CHECK: copy_addr
// CHECK: witness_method
// CHECK: apply
// CHECK: destroy_addr
// CHECK: dealloc_stack
// CHECK: return
// CHECK: } // end sil function 'witness_global_addr_fail_1'
sil @witness_global_addr_fail_1: $@convention(thin) (Builtin.Int1) -> Int {
bb0(%0 : $Builtin.Int1):
alloc_global @$global_var
%3 = global_addr @$global_var : $*SomeProtocol
cond_br %0, bb1, bb2
bb1:
br bb3
bb2:
br bb3
bb3:
%6 = init_existential_addr %3 : $*SomeProtocol, $SomeClass
%7 = alloc_ref $SomeClass
store %7 to %6 : $*SomeClass
%8 = alloc_stack $SomeProtocol
copy_addr %3 to [init] %8 : $*SomeProtocol
%9 = open_existential_addr immutable_access %8 : $*SomeProtocol to $*@opened("2B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self
%10 = witness_method $@opened("2B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self, #SomeProtocol.foo : <Self where Self : SomeProtocol> (Self) -> () -> Int, %9 : $*@opened("2B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self : $@convention(witness_method: SomeProtocol) <τ_0_0 where τ_0_0 : SomeProtocol> (@in_guaranteed τ_0_0) -> Int
%11 = apply %10<@opened("2B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self>(%9) : $@convention(witness_method: SomeProtocol) <τ_0_0 where τ_0_0 : SomeProtocol> (@in_guaranteed τ_0_0) -> Int
destroy_addr %8 : $*SomeProtocol
dealloc_stack %8 : $*SomeProtocol
return %11 : $Int
}
// CHECK-LABEL: sil @witness_global_addr_fail_2
// CHECK: bb0
// CHECK: alloc_global
// CHECK: global_addr
// CHECK: init_existential_addr
// CHECK: alloc_ref
// CHECK: store
// CHECK: init_existential_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: } // end sil function 'witness_global_addr_fail_2'
sil @witness_global_addr_fail_2 : $@convention(thin) () -> Int {
bb0:
alloc_global @$global_var
%3 = global_addr @$global_var : $*SomeProtocol
%4 = init_existential_addr %3 : $*SomeProtocol, $SomeClass
%5 = alloc_ref $SomeClass
store %5 to %4 : $*SomeClass
%6 = init_existential_addr %3 : $*SomeProtocol, $SomeClass
%8 = alloc_stack $SomeProtocol
copy_addr %3 to [init] %8 : $*SomeProtocol
%9 = open_existential_addr immutable_access %8 : $*SomeProtocol to $*@opened("3B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self
%10 = witness_method $@opened("3B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self, #SomeProtocol.foo : <Self where Self : SomeProtocol> (Self) -> () -> Int, %9 : $*@opened("3B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self : $@convention(witness_method: SomeProtocol) <τ_0_0 where τ_0_0 : SomeProtocol> (@in_guaranteed τ_0_0) -> Int
%11 = apply %10<@opened("3B0A5B84-3441-11E8-AC03-DCA9048B1C6D", SomeProtocol) Self>(%9) : $@convention(witness_method: SomeProtocol) <τ_0_0 where τ_0_0 : SomeProtocol> (@in_guaranteed τ_0_0) -> Int
destroy_addr %8 : $*SomeProtocol
dealloc_stack %8 : $*SomeProtocol
return %11 : $Int
}
sil_vtable SomeClass {
#SomeClass.foo: (SomeClass) -> () -> Int : @foo
}
sil_witness_table hidden SomeClass: SomeProtocol module test {
method #SomeProtocol.foo: <Self where Self : SomeProtocol> (Self) -> () -> Int : @foo_
}
|