mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Type annotations for instruction operands are omitted, e.g. ``` %3 = struct $S(%1, %2) ``` Operand types are redundant anyway and were only used for sanity checking in the SIL parser. But: operand types _are_ printed if the definition of the operand value was not printed yet. This happens: * if the block with the definition appears after the block where the operand's instruction is located * if a block or instruction is printed in isolation, e.g. in a debugger The old behavior can be restored with `-Xllvm -sil-print-types`. This option is added to many existing test files which check for operand types in their check-lines.
232 lines
7.8 KiB
Plaintext
232 lines
7.8 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -specdevirt -code-sinking -dce -early-codemotion -disable-sil-cm-rr-cm=0 -retain-sinking | %FileCheck %s
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
class A {
|
|
func ping(x: Builtin.Int32) -> Builtin.Int32
|
|
}
|
|
|
|
class B : A {
|
|
override func ping(x: Builtin.Int32) -> Builtin.Int32
|
|
}
|
|
|
|
class C : A {
|
|
override func ping(x: Builtin.Int32) -> Builtin.Int32
|
|
}
|
|
|
|
class D : C {
|
|
override func ping(x: Builtin.Int32) -> Builtin.Int32
|
|
}
|
|
|
|
sil @external_func : $@convention(thin) (A) -> Builtin.Int32
|
|
|
|
sil @_TFC25polymorphic_inline_caches1A4pingfS0_FBi32_Bi32_ : $@convention(method) (Builtin.Int32, @guaranteed A) -> Builtin.Int32
|
|
sil @_TFC25polymorphic_inline_caches1B4pingfS0_FBi32_Bi32_ : $@convention(method) (Builtin.Int32, @guaranteed B) -> Builtin.Int32
|
|
sil @_TFC25polymorphic_inline_caches1C4pingfS0_FBi32_Bi32_ : $@convention(method) (Builtin.Int32, @guaranteed C) -> Builtin.Int32
|
|
sil @_TFC25polymorphic_inline_caches1D4pingfS0_FBi32_Bi32_ : $@convention(method) (Builtin.Int32, @guaranteed D) -> Builtin.Int32
|
|
|
|
// CHECK-LABEL: sil @_TF25polymorphic_inline_caches3fooFTCS_1ABi32__Bi32_
|
|
sil @_TF25polymorphic_inline_caches3fooFTCS_1ABi32__Bi32_ : $@convention(thin) (@owned A, Builtin.Int32) -> Builtin.Int32 {
|
|
// CHECK: bb0
|
|
bb0(%0 : $A, %1 : $Builtin.Int32):
|
|
// CHECK-NOT: strong_retain %0
|
|
strong_retain %0 : $A
|
|
// CHECK-NOT: class_method
|
|
%5 = class_method %0 : $A, #A.ping : (A) -> (Builtin.Int32) -> Builtin.Int32, $@convention(method) (Builtin.Int32, @guaranteed A) -> Builtin.Int32
|
|
// CHECK-NOT: apply
|
|
%6 = apply %5(%1, %0) : $@convention(method) (Builtin.Int32, @guaranteed A) -> Builtin.Int32
|
|
// CHECK: checked_cast_br [exact] A in %0 : $A to A, bb2, bb3
|
|
// CHECK: bb1
|
|
strong_release %0 : $A
|
|
// CHECK: return
|
|
return %6 : $Builtin.Int32
|
|
// CHECK: bb2
|
|
// CHECK: [[APING:%.*]] = function_ref @_TFC25polymorphic_inline_caches1A4pingfS0_FBi32_Bi32_
|
|
// CHECK: apply [[APING]]
|
|
// CHECK: bb3
|
|
// CHECK: checked_cast_br [exact] A in %0 : $A to B, bb5, bb6
|
|
// CHECK: bb4
|
|
// CHECK: br bb1
|
|
// CHECK: bb5
|
|
// CHECK: [[BPING:%.*]] = function_ref @_TFC25polymorphic_inline_caches1B4pingfS0_FBi32_Bi32_
|
|
// CHECK: apply [[BPING]]
|
|
// CHECK: bb6
|
|
// CHECK: checked_cast_br [exact] A in %0 : $A to C, bb8, bb9
|
|
// CHECK: bb7
|
|
// CHECK: br bb4
|
|
// CHECK: bb8
|
|
// CHECK: [[CPING:%.*]] = function_ref @_TFC25polymorphic_inline_caches1C4pingfS0_FBi32_Bi32_
|
|
// CHECK: apply [[CPING]]
|
|
// CHECK: bb9
|
|
// CHECK: [[PING:%.*]] = class_method %0 : $A, #A.ping
|
|
// CHECK: apply [[PING]]
|
|
}
|
|
|
|
// CHECK-LABEL: sil @polymorphic_inline_caches_dont_sink_retain
|
|
sil @polymorphic_inline_caches_dont_sink_retain : $@convention(thin) (@owned A, Builtin.Int32) -> Builtin.Int32 {
|
|
// CHECK: bb0
|
|
bb0(%0 : $A, %1 : $Builtin.Int32):
|
|
// CHECK: strong_retain %0
|
|
%4 = function_ref @external_func : $@convention(thin) (A) -> Builtin.Int32
|
|
%5 = class_method %0 : $A, #A.ping : (A) -> (Builtin.Int32) -> Builtin.Int32, $@convention(method) (Builtin.Int32, @guaranteed A) -> Builtin.Int32
|
|
|
|
// Don't sink this retain, because its argument is used by %6 (apply of @external_func)
|
|
strong_retain %0 : $A
|
|
// CHECK-NOT: class_method
|
|
// CHECK: apply
|
|
// CHECK-NOT: apply
|
|
%6 = apply %4(%0) : $@convention(thin) (A) -> Builtin.Int32
|
|
%7 = apply %5(%1, %0) : $@convention(method) (Builtin.Int32, @guaranteed A) -> Builtin.Int32
|
|
// CHECK: checked_cast_br [exact] A in %0 : $A to A, bb2, bb3
|
|
// CHECK: bb1
|
|
strong_release %0 : $A
|
|
// CHECK: return
|
|
return %6 : $Builtin.Int32
|
|
// CHECK: bb2
|
|
// CHECK: [[APING:%.*]] = function_ref @_TFC25polymorphic_inline_caches1A4pingfS0_FBi32_Bi32_
|
|
// CHECK: apply [[APING]]
|
|
// CHECK: bb3
|
|
// CHECK: checked_cast_br [exact] A in %0 : $A to B, bb5, bb6
|
|
// CHECK: bb4
|
|
// CHECK: br bb1
|
|
// CHECK: bb5
|
|
// CHECK: [[BPING:%.*]] = function_ref @_TFC25polymorphic_inline_caches1B4pingfS0_FBi32_Bi32_
|
|
// CHECK: apply [[BPING]]
|
|
// CHECK: bb6
|
|
// CHECK: checked_cast_br [exact] A in %0 : $A to C, bb8, bb9
|
|
// CHECK: bb7
|
|
// CHECK: br bb4
|
|
// CHECK: bb8
|
|
// CHECK: [[CPING:%.*]] = function_ref @_TFC25polymorphic_inline_caches1C4pingfS0_FBi32_Bi32_
|
|
// CHECK: apply [[CPING]]
|
|
// CHECK: bb9
|
|
// CHECK: [[PING:%.*]] = class_method %0 : $A, #A.ping
|
|
// CHECK: apply [[PING]]
|
|
}
|
|
|
|
sil_vtable A {
|
|
#A.ping: @_TFC25polymorphic_inline_caches1A4pingfS0_FBi32_Bi32_
|
|
}
|
|
|
|
sil_vtable B {
|
|
#A.ping: @_TFC25polymorphic_inline_caches1B4pingfS0_FBi32_Bi32_ [override]
|
|
}
|
|
|
|
sil_vtable C {
|
|
#A.ping: @_TFC25polymorphic_inline_caches1C4pingfS0_FBi32_Bi32_ [override]
|
|
}
|
|
|
|
sil_vtable D {
|
|
#A.ping: @_TFC25polymorphic_inline_caches1D4pingfS0_FBi32_Bi32_ [override]
|
|
}
|
|
|
|
protocol P {
|
|
func foo()
|
|
}
|
|
|
|
public class E : P {
|
|
@inline(never) func foo()
|
|
deinit
|
|
init()
|
|
}
|
|
|
|
public class F : E {
|
|
@inline(never) override func foo()
|
|
deinit
|
|
override init()
|
|
}
|
|
|
|
public final class G : E {
|
|
@inline(never) override final func foo()
|
|
deinit
|
|
override init()
|
|
}
|
|
|
|
sil [noinline] @_TFC5casts1E3foofS0_FT_T_ : $@convention(method) (@guaranteed E) -> ()
|
|
sil [noinline] @_TFC5casts1F3foofS0_FT_T_ : $@convention(method) (@guaranteed F) -> ()
|
|
sil [noinline] @_TFC5casts1G3foofS0_FT_T_ : $@convention(method) (@guaranteed G) -> ()
|
|
|
|
// CHECK-LABEL: sil [noinline] @_TF5casts18unchecked_ref_castFBoT_
|
|
sil [noinline] @_TF5casts18unchecked_ref_castFBoT_ : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
// CHECK: bb0
|
|
bb0(%0 : $Builtin.NativeObject):
|
|
strong_retain %0 : $Builtin.NativeObject
|
|
// CHECK: [[CAST:%.*]] = unchecked_ref_cast %0 : $Builtin.NativeObject to $E
|
|
%3 = unchecked_ref_cast %0 : $Builtin.NativeObject to $E
|
|
// CHECK-NOT: class_method
|
|
%4 = class_method %3 : $E, #E.foo : (E) -> () -> (), $@convention(method) (@guaranteed E) -> ()
|
|
%5 = apply %4(%3) : $@convention(method) (@guaranteed E) -> ()
|
|
strong_release %0 : $Builtin.NativeObject
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
// CHECK: checked_cast_br [exact] E in [[CAST]] : $E to E, bb2, bb3
|
|
// CHECK: bb1
|
|
// CHECK: strong_release %0
|
|
// CHECK: return
|
|
// CHECK: bb2
|
|
// CHECK: [[EFOO:%.*]] = function_ref @_TFC5casts1E3foofS0_FT_T_
|
|
// CHECK: strong_retain %0
|
|
// CHECK: apply [[EFOO]]
|
|
// CHECK: bb3
|
|
// CHECK: checked_cast_br [exact] E in [[CAST]] : $E to F, bb5, bb6
|
|
// CHECK: bb4
|
|
// CHECK: br bb1
|
|
// CHECK: bb5
|
|
// CHECK: [[FFOO:%.*]] = function_ref @_TFC5casts1F3foofS0_FT_T_
|
|
// CHECK: strong_retain %0
|
|
// CHECK: apply [[FFOO]]
|
|
// CHECK: bb6
|
|
// CHECK: checked_cast_br [exact] E in [[CAST]] : $E to G, bb8, bb9
|
|
// CHECK: bb7
|
|
// CHECK: bb8
|
|
// CHECK: [[GFOO:%.*]] = function_ref @_TFC5casts1G3foofS0_FT_T_
|
|
// CHECK: strong_retain %0
|
|
// CHECK: apply [[GFOO]]
|
|
// CHECK: bb9
|
|
// CHECK: [[DYNAMIC:%.*]] = class_method [[CAST]] : $E, #E.foo
|
|
// CHECK: strong_retain %0
|
|
// CHECK: apply [[DYNAMIC]]
|
|
}
|
|
|
|
// CHECK-LABEL: sil [noinline] @_TF5casts22unchecked_ref_castFCS_1ET_
|
|
sil [noinline] @_TF5casts22unchecked_ref_castFCS_1ET_ : $@convention(thin) (@owned E) -> () {
|
|
// CHECK: bb0
|
|
bb0(%0 : $E):
|
|
strong_retain %0 : $E
|
|
// CHECK: [[CAST:%.*]] = unchecked_ref_cast %0 : $E to $F
|
|
%3 = unchecked_ref_cast %0 : $E to $F
|
|
// CHECK-NOT: class_method
|
|
%4 = class_method %3 : $F, #F.foo : (F) -> () -> (), $@convention(method) (@guaranteed F) -> ()
|
|
%5 = apply %4(%3) : $@convention(method) (@guaranteed F) -> ()
|
|
strong_release %0 : $E
|
|
%7 = tuple ()
|
|
return %7 : $()
|
|
// CHECK: checked_cast_br [exact] F in [[CAST]] : $F to F, bb2, bb3
|
|
// CHECK: bb1
|
|
// CHECK: strong_release %0
|
|
// CHECK: return
|
|
// CHECK: bb2
|
|
// CHECK: [[FFOO:%.*]] = function_ref @_TFC5casts1F3foofS0_FT_T_
|
|
// CHECK: strong_retain %0
|
|
// CHECK: apply [[FFOO]]
|
|
// CHECK: bb3
|
|
// CHECK: [[DYNAMIC:%.*]] = class_method [[CAST]] : $F, #F.foo
|
|
// CHECK: strong_retain %0
|
|
// CHECK: apply [[DYNAMIC]]
|
|
}
|
|
|
|
sil_vtable E {
|
|
#E.foo: @_TFC5casts1E3foofS0_FT_T_
|
|
}
|
|
|
|
sil_vtable F {
|
|
#E.foo: @_TFC5casts1F3foofS0_FT_T_ [override]
|
|
}
|
|
|
|
sil_vtable G {
|
|
#E.foo: @_TFC5casts1G3foofS0_FT_T_ [override]
|
|
}
|