// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -enable-sil-verify-all %s -devirtualizer -generic-specializer -inline -dce | %FileCheck %s sil_stage canonical import Builtin protocol P { func foo() -> Builtin.Int1 } struct S : P { func foo() -> Builtin.Int1 } private class C : P { func foo() -> Builtin.Int1 } // CHECK-LABEL: struct_target sil [always_inline] @struct_target : $@convention(method) (S) -> Builtin.Int1 { // CHECK: bb0 bb0(%0 : $S): %2 = integer_literal $Builtin.Int1, 0 return %2 : $Builtin.Int1 } // CHECK-LABEL: struct_witness sil [always_inline] [thunk] @struct_witness : $@convention(witness_method: P) (@in_guaranteed S) -> Builtin.Int1 { // CHECK: bb0 bb0(%0 : $*S): // CHECK-NOT: load %1 = load %0 : $*S // CHECK-NOT: function_ref %2 = function_ref @struct_target : $@convention(method) (S) -> Builtin.Int1 // CHECK-NOT: apply %3 = apply %2(%1) : $@convention(method) (S) -> Builtin.Int1 // CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0 // CHECK: return [[ZERO]] return %3 : $Builtin.Int1 } // CHECK-LABEL: struct_caller sil shared @struct_caller : $@convention(thin) (@in S) -> Builtin.Int1 { // CHECK: bb0 bb0(%0 : $*S): // CHECK-NOT: witness_method %2 = witness_method $S, #P.foo!1 : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Builtin.Int1 // CHECK-NOT: apply %3 = apply %2(%0) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Builtin.Int1 // CHECK: [[ZERO:%.*]] = integer_literal $Builtin.Int1, 0 // CHECK: return [[ZERO]] destroy_addr %0 : $*S return %3 : $Builtin.Int1 } // CHECK-LABEL: class_target sil [always_inline] @class_target : $@convention(method) (@guaranteed C) -> Builtin.Int1 { bb0(%0 : $C): %1 = integer_literal $Builtin.Int1, -1 return %1 : $Builtin.Int1 } // CHECK-LABEL: class_witness sil [always_inline] [thunk] @class_witness : $@convention(witness_method: P) (@in_guaranteed C) -> Builtin.Int1 { // CHECK: bb0 bb0(%0 : $*C): // CHECK-NOT: load %1 = load %0 : $*C // CHECK-NOT: class_method %3 = class_method %1 : $C, #C.foo!1 : (C) -> () -> Builtin.Int1, $@convention(method) (@guaranteed C) -> Builtin.Int1 // CHECK-NOT: apply %4 = apply %3(%1) : $@convention(method) (@guaranteed C) -> Builtin.Int1 // CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int1, -1 // CHECK: return [[ONE]] return %4 : $Builtin.Int1 } // CHECK-LABEL: class_caller sil shared @class_caller : $@convention(thin) (@in C) -> Builtin.Int1 { // CHECK: bb0 bb0(%0 : $*C): // CHECK-NOT: witness_method %1 = witness_method $C, #P.foo!1 : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Builtin.Int1 // CHECK-NOT: apply %2 = apply %1(%0) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Builtin.Int1 destroy_addr %0 : $*C // CHECK: [[ONE:%.*]] = integer_literal $Builtin.Int1, -1 // CHECK: return [[ONE]] return %2 : $Builtin.Int1 } sil_vtable C { #C.foo!1: class_target } sil_witness_table C: P module main { method #P.foo!1: @class_witness } sil_witness_table S: P module main { method #P.foo!1: @struct_witness }