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
|
// RUN: %target-swift-frontend %s -emit-ir -disable-objc-interop | %FileCheck %s
// RUN: %target-swift-frontend %s -emit-ir -disable-objc-interop -O | %FileCheck %s --check-prefix=OPT
// REQUIRES: CPU=x86_64
sil_stage canonical
import Swift
protocol P {}
// NonBitwiseTakableBit = 0x00100000. This struct is bitwise takable because
// 0x30007 = 196615
// CHECK: @"$s12existentials14BitwiseTakableVWV" = internal constant %swift.vwtable {{.*}} i32 196615
struct BitwiseTakable {
var p: P
}
protocol CP: class {}
// CHECK-DAG: define{{( dllexport)?}}{{( protected)?}} swiftcc { ptr, ptr } @class_existential_unowned(ptr %0, ptr %1) {{.*}} {
sil @class_existential_unowned : $@convention(thin) (@owned CP) -> @owned CP {
entry(%s : $CP):
%u = ref_to_unowned %s : $CP to $@sil_unowned CP
// CHECK: call ptr @swift_unownedRetain(ptr returned %0)
unowned_retain %u : $@sil_unowned CP
// CHECK: call void @swift_unownedRelease(ptr %0)
unowned_release %u : $@sil_unowned CP
// CHECK: call ptr @swift_unownedRetainStrong(ptr returned %0)
strong_retain_unowned %u : $@sil_unowned CP
%t = unowned_to_ref %u : $@sil_unowned CP to $CP
// CHECK: call void @swift_release(ptr %0)
strong_release %t : $CP
%v = ref_to_unmanaged %s : $CP to $@sil_unmanaged CP
// CHECK: call ptr @swift_retain(ptr returned %0)
%v_copy = strong_copy_unmanaged_value %v : $@sil_unmanaged CP
// CHECK: call void @swift_release(ptr %0)
strong_release %v_copy : $CP
// CHECK: [[RESULT_A:%.*]] = insertvalue { ptr, ptr } undef, ptr %0, 0
// CHECK: [[RESULT_B:%.*]] = insertvalue { ptr, ptr } [[RESULT_A]], ptr %1, 1
%z = unmanaged_to_ref %v : $@sil_unmanaged CP to $CP
// CHECK: ret { ptr, ptr } [[RESULT_B]]
return %z : $CP
}
// CHECK-DAG: define{{( dllexport)?}}{{( protected)?}} swiftcc void @class_existential_weak(ptr noalias sret({{.*}}) %0, i64 %1, i64 %2)
sil @class_existential_weak : $@convention(thin) (@owned CP?) -> @out @sil_weak CP? {
entry(%w : $*@sil_weak CP?, %a : $CP?):
// CHECK: [[V:%.*]] = alloca { %swift.weak, ptr }
%v = alloc_stack $@sil_weak CP?
// CHECK: [[SRC_REF:%.*]] = inttoptr {{.*}} ptr
// CHECK: [[SRC_WITNESS:%.*]] = inttoptr {{.*}} ptr
// CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, ptr }, ptr %0, i32 0, i32 1
// CHECK: store ptr [[SRC_WITNESS]], ptr [[DEST_WITNESS_ADDR]]
// CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, ptr }, ptr %0, i32 0, i32 0
// CHECK: call ptr @swift_weakInit(ptr returned [[DEST_REF_ADDR]], ptr [[SRC_REF]])
store_weak %a to [init] %w : $*@sil_weak CP?
// CHECK: [[SRC_REF:%.*]] = inttoptr {{.*}} ptr
// CHECK: [[SRC_WITNESS:%.*]] = inttoptr {{.*}} ptr
// CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, ptr }, ptr %0, i32 0, i32 1
// CHECK: store ptr [[SRC_WITNESS]], ptr [[DEST_WITNESS_ADDR]]
// CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, ptr }, ptr %0, i32 0, i32 0
// CHECK: call ptr @swift_weakAssign(ptr returned [[DEST_REF_ADDR]], ptr [[SRC_REF]])
store_weak %a to %w : $*@sil_weak CP?
// CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, ptr }, ptr %0, i32 0, i32 0
// CHECK: [[DEST_REF:%.*]] = call ptr @swift_weakTakeStrong(ptr [[SRC_REF_ADDR]])
// CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, ptr }, ptr %0, i32 0, i32 1
// CHECK: [[DEST_WITNESS:%.*]] = load ptr, ptr [[SRC_WITNESS_ADDR]]
%b = load_weak [take] %w : $*@sil_weak CP?
// CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, ptr }, ptr %0, i32 0, i32 0
// CHECK: [[DEST_REF:%.*]] = call ptr @swift_weakLoadStrong(ptr [[SRC_REF_ADDR]])
// CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, ptr }, ptr %0, i32 0, i32 1
// CHECK: [[DEST_WITNESS:%.*]] = load ptr, ptr [[SRC_WITNESS_ADDR]]
%c = load_weak %w : $*@sil_weak CP?
// CHECK: call ptr @"$s12existentials2CP_pSgXwWOb"(ptr %0, ptr [[V]])
copy_addr [take] %w to [init] %v : $*@sil_weak CP?
// CHECK: call ptr @"$s12existentials2CP_pSgXwWOd"(ptr %0, ptr [[V]])
copy_addr [take] %w to %v : $*@sil_weak CP?
// CHECK: call ptr @"$s12existentials2CP_pSgXwWOc"(ptr %0, ptr [[V]])
copy_addr %w to [init] %v : $*@sil_weak CP?
// CHECK: call ptr @"$s12existentials2CP_pSgXwWOf"(ptr %0, ptr [[V]])
copy_addr %w to %v : $*@sil_weak CP?
// CHECK: call ptr @"$s12existentials2CP_pSgXwWOh"(ptr [[V]])
destroy_addr %v : $*@sil_weak CP?
dealloc_stack %v : $*@sil_weak CP?
return undef : $()
}
protocol Constrained<T> {
associatedtype T
}
sil @keep_alive : $@convention(thin)(@inout any Constrained<Int>) -> ()
sil @constrained_protocol : $@convention(thin) (@inout any Constrained<Int>) -> () {
entry(%arg : $*any Constrained<Int>):
%dst = alloc_stack $any Constrained<Int>
copy_addr %arg to [init] %dst : $*any Constrained<Int>
%fn = function_ref @keep_alive : $@convention(thin)(@inout any Constrained<Int>) -> ()
apply %fn(%dst) : $@convention(thin)(@inout any Constrained<Int>) -> ()
destroy_addr %dst : $*any Constrained<Int>
dealloc_stack %dst : $*any Constrained<Int>
%t = tuple ()
return %t : $()
}
// Make sure we don't instantiate metadata for constrained existentials. Metadata
// instatiation is not supported on older runtimes.
// OPT: define{{.*}} void @constrained_protocol(
// OPT: call {{.*}} @"$s12existentials11Constrained_pSi1TAaBPRts_XPWOc"
// OPT: define{{.*}} @"$s12existentials11Constrained_pSi1TAaBPRts_XPWOc"
// OPT-NOT: call {{.*}} instantiate
// OPT-NOT: ret
// OPT: load
// OPT: store
// OPT: call
// OPT: ret
|