blob: 04cead7feb871a0727c10aeeff566e2897bec31f [file] [log] [blame]
// RUN: %target-sil-opt -enable-sil-verify-all %s -inline -devirtualizer | %FileCheck %s
sil_stage canonical
import Builtin
import Swift
class Hash {
func update()
func hash()
}
class MD5 : Hash {
override init()
override func hash()
}
sil [ossa] @_TFC4test3MD5cfMS0_FT_S0_ : $@convention(method) (@owned MD5) -> @owned MD5 {
bb0(%0 : @owned $MD5):
return %0 : $MD5
}
sil @_TFC4test3MD54hashfS0_FT3MsgVs5UInt8_T_ : $@convention(method) (@guaranteed MD5) -> ()
sil @_TFC4test4Hash4hashfS0_FT3MsgVs5UInt8_T_ : $@convention(method) (@guaranteed Hash) -> ()
sil @_TFC9hash2_new4Hash6updatefS0_FT3MsgVs5UInt83CntSi_T_ : $@convention(method) (@guaranteed Hash) -> ()
// CHECK-LABEL: @_TF4test8testHashFT_T_
sil [ossa] @_TF4test8testHashFT_T_ : $@convention(thin) () -> () {
bb0:
%0 = alloc_ref $MD5
%1 = function_ref @_TFC4test3MD5cfMS0_FT_S0_ : $@convention(method) (@owned MD5) -> @owned MD5
%2 = apply %1(%0) : $@convention(method) (@owned MD5) -> @owned MD5
%3 = copy_value %2 : $MD5
%69 = upcast %3 : $MD5 to $Hash
%70 = copy_value %69 : $Hash
// CHECK: function_ref @_TFC4test3MD54hashfS0_FT3MsgVs5UInt8_T_ : $@convention(method) (@guaranteed MD5) -> ()
// CHECK: apply {{%[0-9]+}}({{%[0-9]+}}) : $@convention(method) (@guaranteed MD5) -> ()
%134 = class_method %70 : $Hash, #Hash.hash!1 : (Hash) -> () -> (), $@convention(method) (@guaranteed Hash) -> ()
%135 = apply %134(%70) : $@convention(method) (@guaranteed Hash) -> ()
destroy_value %70 : $Hash
destroy_value %69 : $Hash
destroy_value %2 : $MD5
%17 = tuple ()
return %17 : $()
}
// CHECK-LABEL: @test_unchecked_ref
sil [ossa] @test_unchecked_ref : $@convention(thin) () -> () {
bb0:
%0 = alloc_ref $MD5
%11 = upcast %0 : $MD5 to $Hash
%21 = unchecked_ref_cast %11 : $Hash to $MD5
%61 = upcast %21 : $MD5 to $Hash
// CHECK: function_ref @_TFC9hash2_new4Hash6updatefS0_FT3MsgVs5UInt83CntSi_T_ : $@convention(method) (@guaranteed Hash) -> ()
// CHECK: apply {{%[0-9]+}}({{%[0-9]+}}) : $@convention(method) (@guaranteed Hash) -> ()
%62 = class_method %61 : $Hash, #Hash.update!1 : (Hash) -> () -> (), $@convention(method) (@guaranteed Hash) -> ()
%135 = apply %62(%61) : $@convention(method) (@guaranteed Hash) -> ()
destroy_value %61 : $Hash
%17 = tuple ()
// CHECK: return
return %17 : $()
}
sil_vtable Hash {
#Hash.update!1: @_TFC9hash2_new4Hash6updatefS0_FT3MsgVs5UInt83CntSi_T_
#Hash.hash!1: @_TFC4test4Hash4hashfS0_FT3MsgVs5UInt8_T_
}
sil_vtable MD5 {
// vtable should be keyed with the least-derived method, otherwise
// devirtualizer will choose the wrong function ref.
#Hash.hash!1: @_TFC4test3MD54hashfS0_FT3MsgVs5UInt8_T_
#MD5.init!initializer.1: @_TFC4test3MD5cfMS0_FT_S0_
#Hash.update!1: @_TFC9hash2_new4Hash6updatefS0_FT3MsgVs5UInt83CntSi_T_
}
class C {
func doIt()
}
class D : C {
override func doIt()
}
class E : D {
override func doIt()
}
// CHECK-LABEL: sil [ossa] @_TFC1b1C4doItfS0_FT_T_
sil [ossa] @_TFC1b1C4doItfS0_FT_T_ : $@convention(method) (@guaranteed C) -> () {
bb0(%0 : @guaranteed $C):
%2 = tuple ()
return %2 : $()
}
// CHECK-LABEL: sil [ossa] @_TFC1b1D4doItfS0_FT_T_
sil [ossa] @_TFC1b1D4doItfS0_FT_T_ : $@convention(method) (@guaranteed D) -> () {
bb0(%0 : @guaranteed $D):
%2 = tuple ()
return %2 : $()
}
// CHECK-LABEL: sil [ossa] @_TFC1b1E4doItfS0_FT_T_
sil [ossa] @_TFC1b1E4doItfS0_FT_T_ : $@convention(method) (@guaranteed E) -> () {
bb0(%0 : @guaranteed $E):
%2 = tuple ()
return %2 : $()
}
// CHECK-LABEL: sil [ossa] @_TF1b3fooFT_T_
sil [ossa] @_TF1b3fooFT_T_ : $@convention(thin) () -> () {
bb0:
%0 = alloc_ref $E
%1 = upcast %0 : $E to $C
%2 = unconditional_checked_cast %1 : $C to $D
%3 = class_method %2 : $D, #D.doIt!1 : (D) -> () -> (), $@convention(method) (@guaranteed D) -> ()
%4 = apply %3(%2) : $@convention(method) (@guaranteed D) -> ()
destroy_value %2 : $D
%5 = tuple ()
// CHECK: return
return %5 : $()
}
sil_vtable C {
#C.doIt!1: @_TFC1b1C4doItfS0_FT_T_
}
sil_vtable D {
#C.doIt!1: @_TFC1b1D4doItfS0_FT_T_
}
sil_vtable E {
#C.doIt!1: @_TFC1b1E4doItfS0_FT_T_
}