blob: 91215a0035af4fec8018c5fbe1cbce3dd0b52dd2 [file] [log] [blame]
// RUN: %target-sil-opt -O -wmo -enable-sil-verify-all -sil-disable-pass=DeadFunctionElimination %s | %FileCheck %s
sil_stage canonical
import Swift
protocol ClassProtocol: AnyObject { func method() }
class C: ClassProtocol { func method() {} }
// CHECK-LABEL: sil [signature_optimized_thunk] [always_inline] @test_indirect_class_protocol : $@convention(thin) (@in ClassProtocol) -> ()
sil @test_indirect_class_protocol : $@convention(thin) (@in ClassProtocol) -> () {
// CHECK-NEXT: //
// CHECK-NEXT: bb0(%0 : $*ClassProtocol):
bb0(%0 : $*ClassProtocol):
// CHECK-NEXT: %1 = load %0
// CHECK-NEXT: strong_release %1
destroy_addr %0 : $*ClassProtocol
// CHECK-NEXT: return undef
return undef : $()
}
// Check that all the opened types are optimized away in the specialization of test_indirect_class_protocol_guaranteed
// CHECK-LABEL: sil shared @$s39test_indirect_class_protocol_guaranteedTf4e_n : $@convention(thin) <τ_0_0 where τ_0_0 : ClassProtocol> (@in_guaranteed τ_0_0) -> ()
// CHECK-NEXT: //
// CHECK-NEXT: bb0(%0 : $*τ_0_0):
// CHECK-NEXT: [[INPUT:%1]] = load %0
// CHECK-NEXT: [[METHOD:%.*]] = witness_method $C, #ClassProtocol.method
// CHECK-NEXT: [[ARG:%.*]] = unchecked_ref_cast [[INPUT]]
// CHECK-NEXT: apply [[METHOD]]<C>([[ARG]])
// CHECK-NEXT: return undef
sil @test_indirect_class_protocol_guaranteed : $@convention(thin) (@in_guaranteed ClassProtocol) -> () {
bb0(%0 : $*ClassProtocol):
%1 = load %0 : $*ClassProtocol
%2 = open_existential_ref %1 : $ClassProtocol to $@opened("ABCDEF01-ABCD-ABCD-ABCD-ABCDEFABCDEF") ClassProtocol
%f = witness_method $@opened("ABCDEF01-ABCD-ABCD-ABCD-ABCDEFABCDEF") ClassProtocol, #ClassProtocol.method : <Self: ClassProtocol> (Self) -> () -> (), %2 : $@opened("ABCDEF01-ABCD-ABCD-ABCD-ABCDEFABCDEF") ClassProtocol : $@convention(witness_method : ClassProtocol) <Self: ClassProtocol> (@guaranteed Self) -> ()
apply %f<@opened("ABCDEF01-ABCD-ABCD-ABCD-ABCDEFABCDEF") ClassProtocol>(%2) : $@convention(witness_method : ClassProtocol) <Self: ClassProtocol> (@guaranteed Self) -> ()
return undef : $()
}
// Check that a specialization of test_indirect_class_protocol is created.
// CHECK-LABEL: sil shared [signature_optimized_thunk] [always_inline] @$s28test_indirect_class_protocolTf4e_n4main1CC_Tg5 : $@convention(thin) (@owned C) -> ()
// CHECK-NEXT: //
// CHECK-NEXT: bb0(%0 : $C):
// CHECK-NEXT: strong_release %0
// CHECK-NEXT: return undef
// CHECK-LABEL: end sil function '$s28test_indirect_class_protocolTf4e_n4main1CC_Tg5'
// Check the generated specialization of test_indirect_class_protocol
// CHECK-LABEL: sil shared @$s28test_indirect_class_protocolTf4e_n4main1CC_Tg5Tf4d_n : $@convention(thin) () -> ()
// Make sure *everything* was inlined / optimized away
// CHECK-NEXT: bb0:
// CHECK-NEXT: return undef
sil @invoke_indirect_class_protocol : $@convention(thin) (@guaranteed C) -> () {
bb0(%0 : $C):
%1 = init_existential_ref %0 : $C : $C, $ClassProtocol
%z = alloc_stack $ClassProtocol
retain_value %1 : $ClassProtocol
store %1 to %z : $*ClassProtocol
%f = function_ref @test_indirect_class_protocol_guaranteed : $@convention(thin) (@in_guaranteed ClassProtocol) -> ()
apply %f(%z) : $@convention(thin) (@in_guaranteed ClassProtocol) -> ()
%g = function_ref @test_indirect_class_protocol : $@convention(thin) (@in ClassProtocol) -> ()
apply %g(%z) : $@convention(thin) (@in ClassProtocol) -> ()
dealloc_stack %z : $*ClassProtocol
return undef : $()
}