blob: a0e25dec8f88992159656ce7e2e758cd0f28df03 [file] [log] [blame]
// RUN: %target-swift-frontend %s -emit-ir -disable-objc-interop | FileCheck %s
// REQUIRES: CPU=x86_64
sil_stage canonical
import Swift
protocol CP: class {}
// CHECK-DAG: define{{( protected)?}} { %swift.refcounted*, i8** } @class_existential_unowned(%swift.refcounted*, i8**) {{.*}} {
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 void @rt_swift_unownedRetain(%swift.refcounted* %0)
unowned_retain %u : $@sil_unowned CP
// CHECK: call void @rt_swift_unownedRelease(%swift.refcounted* %0)
unowned_release %u : $@sil_unowned CP
// CHECK: call void @rt_swift_unownedRetainStrong(%swift.refcounted* %0)
strong_retain_unowned %u : $@sil_unowned CP
%t = unowned_to_ref %u : $@sil_unowned CP to $CP
// CHECK: call void @rt_swift_release(%swift.refcounted* %0)
strong_release %t : $CP
%v = ref_to_unmanaged %s : $CP to $@sil_unmanaged CP
%z = unmanaged_to_ref %v : $@sil_unmanaged CP to $CP
// CHECK: [[RESULT_A:%.*]] = insertvalue { %swift.refcounted*, i8** } undef, %swift.refcounted* %0, 0
// CHECK: [[RESULT_B:%.*]] = insertvalue { %swift.refcounted*, i8** } [[RESULT_A]], i8** %1, 1
// CHECK: ret { %swift.refcounted*, i8** } [[RESULT_B]]
return %z : $CP
}
// CHECK-DAG: define{{( protected)?}} void @class_existential_weak({ %swift.weak, i8** }* noalias nocapture sret, i64, i64)
sil @class_existential_weak : $@convention(thin) (@owned CP?) -> @out @sil_weak CP? {
entry(%w : $*@sil_weak CP?, %a : $CP?):
// CHECK: [[V:%.*]] = alloca { %swift.weak, i8** }
%v = alloc_stack $@sil_weak CP?
// CHECK: [[SRC_REF:%.*]] = inttoptr {{.*}} %swift.refcounted*
// CHECK: [[SRC_WITNESS:%.*]] = inttoptr {{.*}} i8**
// CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
// CHECK: store i8** [[SRC_WITNESS]], i8*** [[DEST_WITNESS_ADDR]]
// CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
// CHECK: call void @swift_weakInit(%swift.weak* [[DEST_REF_ADDR]], %swift.refcounted* [[SRC_REF]])
store_weak %a to [initialization] %w : $*@sil_weak CP?
// CHECK: [[SRC_REF:%.*]] = inttoptr {{.*}} %swift.refcounted*
// CHECK: [[SRC_WITNESS:%.*]] = inttoptr {{.*}} i8**
// CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
// CHECK: store i8** [[SRC_WITNESS]], i8*** [[DEST_WITNESS_ADDR]]
// CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
// CHECK: call void @swift_weakAssign(%swift.weak* [[DEST_REF_ADDR]], %swift.refcounted* [[SRC_REF]])
store_weak %a to %w : $*@sil_weak CP?
// CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
// CHECK: [[DEST_REF:%.*]] = call %swift.refcounted* @swift_weakTakeStrong(%swift.weak* [[SRC_REF_ADDR]])
// CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
// CHECK: [[DEST_WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]]
%b = load_weak [take] %w : $*@sil_weak CP?
// CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
// CHECK: [[DEST_REF:%.*]] = call %swift.refcounted* @swift_weakLoadStrong(%swift.weak* [[SRC_REF_ADDR]])
// CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
// CHECK: [[DEST_WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]]
%c = load_weak %w : $*@sil_weak CP?
// CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 0
// CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
// CHECK: call void @swift_weakTakeInit(%swift.weak* [[DEST_REF_ADDR]], %swift.weak* [[SRC_REF_ADDR]])
// CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
// CHECK: [[WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]], align 8
// CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 1
// CHECK: store i8** [[WITNESS]], i8*** [[DEST_WITNESS_ADDR]], align 8
copy_addr [take] %w to [initialization] %v : $*@sil_weak CP?
// CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 0
// CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
// CHECK: call void @swift_weakTakeAssign(%swift.weak* [[DEST_REF_ADDR]], %swift.weak* [[SRC_REF_ADDR]])
// CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
// CHECK: [[WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]], align 8
// CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 1
// CHECK: store i8** [[WITNESS]], i8*** [[DEST_WITNESS_ADDR]], align 8
copy_addr [take] %w to %v : $*@sil_weak CP?
// CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 0
// CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
// CHECK: call void @swift_weakCopyInit(%swift.weak* [[DEST_REF_ADDR]], %swift.weak* [[SRC_REF_ADDR]])
// CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
// CHECK: [[WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]], align 8
// CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 1
// CHECK: store i8** [[WITNESS]], i8*** [[DEST_WITNESS_ADDR]], align 8
copy_addr %w to [initialization] %v : $*@sil_weak CP?
// CHECK: [[DEST_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 0
// CHECK: [[SRC_REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 0
// CHECK: call void @swift_weakCopyAssign(%swift.weak* [[DEST_REF_ADDR]], %swift.weak* [[SRC_REF_ADDR]])
// CHECK: [[SRC_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* %0, i32 0, i32 1
// CHECK: [[WITNESS:%.*]] = load i8**, i8*** [[SRC_WITNESS_ADDR]], align 8
// CHECK: [[DEST_WITNESS_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 1
// CHECK: store i8** [[WITNESS]], i8*** [[DEST_WITNESS_ADDR]], align 8
copy_addr %w to %v : $*@sil_weak CP?
// CHECK: [[REF_ADDR:%.*]] = getelementptr inbounds { %swift.weak, i8** }, { %swift.weak, i8** }* [[V]], i32 0, i32 0
// CHECK: call void @swift_weakDestroy(%swift.weak* [[REF_ADDR]])
destroy_addr %v : $*@sil_weak CP?
dealloc_stack %v : $*@sil_weak CP?
return undef : $()
}