mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
These were added in https://github.com/swiftlang/swift/pull/81375 (and several other follow-up PRs because we missed a few places) and are no longer needed.
225 lines
8.7 KiB
Plaintext
225 lines
8.7 KiB
Plaintext
// RUN: %empty-directory(%t)
|
|
// RUN: %build-irgen-test-overlays
|
|
// RUN: %target-swift-frontend -disable-type-layout -sdk %S/Inputs -I %t %s -emit-ir | %FileCheck %s
|
|
|
|
// REQUIRES: CPU=x86_64
|
|
// REQUIRES: objc_interop
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import gizmo
|
|
|
|
typealias AnyObject = Builtin.AnyObject
|
|
|
|
// rdar://16621578
|
|
|
|
sil @init_opaque_existential : $@convention(thin) <T where T : Gizmo> (@owned T) -> @out Any {
|
|
bb0(%0 : $*Any, %1 : $T):
|
|
%2 = init_existential_addr %0 : $*Any, $T
|
|
store %1 to %2 : $*T
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-DAG: define{{( protected)?}} swiftcc void @init_opaque_existential(ptr noalias sret({{.*}}) captures(none) %0, ptr %1, ptr %T) {{.*}} {
|
|
// CHECK: [[T0:%.*]] = getelementptr inbounds{{.*}} [[ANY:%Any]], ptr %0, i32 0, i32 1
|
|
// CHECK-NEXT: store ptr %T, ptr [[T0]], align 8
|
|
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds{{.*}} [[ANY]], ptr %0, i32 0, i32 0
|
|
// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds{{.*}} [[ANY]], ptr %0, i32 0, i32 0
|
|
// CHECK-NEXT: store ptr %1, ptr [[T0]], align 8
|
|
// CHECK-NEXT: ret void
|
|
|
|
sil @take_opaque_existential : $@convention(thin) (@in Any) -> @out Any {
|
|
bb0(%0 : $*Any, %1 : $*Any):
|
|
copy_addr [take] %1 to [init] %0 : $*Any
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-DAG: define{{( protected)?}} swiftcc void @take_opaque_existential(ptr noalias sret({{.*}}) captures(none) %0, ptr noalias captures(none) dereferenceable({{.*}}) %1) {{.*}} {
|
|
// CHECK: call ptr @"$sypWOb"(ptr %1, ptr %0)
|
|
// CHECK-NEXT: ret void
|
|
|
|
// CHECK-DAG: define linkonce_odr hidden ptr @"$sypWOb"(ptr %0, ptr %1)
|
|
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %1, ptr align 8 %0, i64 32, i1 false)
|
|
// CHECK-NEXT: ret ptr %1
|
|
|
|
// rdar://problem/19035529
|
|
@objc protocol OP {}
|
|
@objc protocol OP2: OP {}
|
|
|
|
// CHECK-DAG: define{{( protected)?}} swiftcc ptr @init_existential_objc_to_objc(ptr %0) {{.*}} {
|
|
// CHECK: ret ptr %0
|
|
sil @init_existential_objc_to_objc : $@convention(thin) (@owned OP2) -> @owned OP {
|
|
entry(%o : $OP2):
|
|
%a = init_existential_ref %o : $OP2 : $OP2, $OP
|
|
return %a : $OP
|
|
}
|
|
|
|
protocol CP: class {}
|
|
|
|
// CHECK-DAG: define{{( protected)?}} swiftcc { ptr, ptr } @class_existential_unowned(ptr %0, ptr %1) {{.*}} {
|
|
sil @class_existential_unowned : $@convention(thin) (@owned CP) -> @owned CP {
|
|
entry(%s : $CP):
|
|
%u1 = alloc_stack $@sil_unowned CP
|
|
%u2 = alloc_stack $@sil_unowned CP
|
|
// CHECK: [[U1:%.*]] = alloca [[UREF:{ %swift.unowned, ptr }]], align 8
|
|
// CHECK: [[U2:%.*]] = alloca [[UREF]], align 8
|
|
|
|
store_unowned %s to [init] %u1 : $*@sil_unowned CP
|
|
// CHECK: [[T0:%.*]] = getelementptr inbounds{{.*}} [[UREF]], ptr [[U1]], i32 0, i32 1
|
|
// CHECK: store ptr %1, ptr [[T0]], align 8
|
|
// CHECK: [[T0:%.*]] = getelementptr inbounds{{.*}} [[UREF]], ptr [[U1]], i32 0, i32 0
|
|
// CHECK: call ptr @swift_unknownObjectUnownedInit(ptr returned [[T0]], ptr %0)
|
|
|
|
// CHECK: [[T0:%.*]] = getelementptr inbounds{{.*}} [[UREF]], ptr [[U1]], i32 0, i32 0
|
|
// CHECK: [[T1:%.*]] = call ptr @swift_unknownObjectUnownedLoadStrong(ptr [[T0]])
|
|
%t = load_unowned %u1 : $*@sil_unowned CP
|
|
// CHECK: call void @swift_unknownObjectRelease(ptr [[T1]])
|
|
strong_release %t : $CP
|
|
|
|
dealloc_stack %u2 : $*@sil_unowned CP
|
|
dealloc_stack %u1 : $*@sil_unowned CP
|
|
|
|
%v = ref_to_unmanaged %s : $CP to $@sil_unmanaged CP
|
|
// CHECK: call ptr @swift_unknownObjectRetain(ptr
|
|
%v_copy = strong_copy_unmanaged_value %v : $@sil_unmanaged CP
|
|
// CHECK: call void @swift_unknownObjectRelease(ptr
|
|
strong_release %v_copy : $CP
|
|
|
|
%z = unmanaged_to_ref %v : $@sil_unmanaged CP to $CP
|
|
|
|
// CHECK: [[RESULT_A:%.*]] = insertvalue { ptr, ptr } undef, ptr %0, 0
|
|
// CHECK: [[RESULT_B:%.*]] = insertvalue { ptr, ptr } [[RESULT_A]], ptr %1, 1
|
|
// CHECK: ret { ptr, ptr } [[RESULT_B]]
|
|
|
|
return %z : $CP
|
|
}
|
|
|
|
// CHECK-DAG: define{{( 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_unknownObjectWeakInit(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_unknownObjectWeakAssign(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_unknownObjectWeakTakeStrong(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_unknownObjectWeakLoadStrong(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 @"$s17existentials_objc2CP_pSgXwWOb"(ptr %0, ptr [[V]])
|
|
copy_addr [take] %w to [init] %v : $*@sil_weak CP?
|
|
|
|
// CHECK: call ptr @"$s17existentials_objc2CP_pSgXwWOd"(ptr %0, ptr [[V]])
|
|
copy_addr [take] %w to %v : $*@sil_weak CP?
|
|
|
|
// CHECK: call ptr @"$s17existentials_objc2CP_pSgXwWOc"(ptr %0, ptr [[V]])
|
|
copy_addr %w to [init] %v : $*@sil_weak CP?
|
|
|
|
// CHECK: call ptr @"$s17existentials_objc2CP_pSgXwWOf"(ptr %0, ptr [[V]])
|
|
copy_addr %w to %v : $*@sil_weak CP?
|
|
|
|
// CHECK: call ptr @"$s17existentials_objc2CP_pSgXwWOh"(ptr [[V]])
|
|
destroy_addr %v : $*@sil_weak CP?
|
|
|
|
dealloc_stack %v : $*@sil_weak CP?
|
|
|
|
return undef : $()
|
|
}
|
|
|
|
@objc protocol ProtocolA : class {
|
|
@objc optional func funcA()
|
|
}
|
|
|
|
// CHECK: define swiftcc void @useObjcProtocol(ptr swiftself %0)
|
|
// CHECK: entry:
|
|
// CHECK: load ptr, ptr @"\01L_selector(funcA)"
|
|
// CHECK: load ptr, ptr @"\01L_selector(respondsToSelector:)"
|
|
// CHECK: [[TMP:%.*]] = call i1 @objc_msgSend
|
|
// CHECK: br i1 [[TMP]]
|
|
//
|
|
// CHECK: call void @objc_msgSend(ptr %0
|
|
// CHECK: ret void
|
|
// CHECK: }
|
|
|
|
sil public @useObjcProtocol : $@convention(method) (@guaranteed ProtocolA) -> () {
|
|
bb0(%0 : $ProtocolA):
|
|
dynamic_method_br %0 : $ProtocolA, #ProtocolA.funcA!foreign, bb1, bb2
|
|
|
|
bb1(%1 : $@convention(objc_method) (ProtocolA) -> ()):
|
|
%3 = apply %1(%0) : $@convention(objc_method) (ProtocolA) -> ()
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
%4 = tuple()
|
|
return %4 : $()
|
|
}
|
|
|
|
protocol TestP : AnyObject {}
|
|
|
|
class NSObject {}
|
|
|
|
class TestC {
|
|
@_hasStorage unowned final let t: @sil_unowned NSObject & TestP
|
|
init(t: NSObject & TestP)
|
|
}
|
|
|
|
// CHECK-LABEL: define {{.*}}@test_load_unowned
|
|
// CHECK: [[REF:%.*]] = load ptr, ptr
|
|
// CHECK: swift_unownedRetainStrong
|
|
// CHECK: [[EXIST0:%.*]] = insertvalue { ptr, ptr } undef, ptr [[REF]], 0
|
|
// CHECK: [[EXIST:%.*]] = insertvalue { ptr, ptr } [[EXIST0]], ptr {{.*}}, 1
|
|
// CHECK: ret { ptr, ptr } [[EXIST]]
|
|
|
|
sil @test_load_unowned : $@convention(method) (@guaranteed TestC) -> @owned NSObject & TestP {
|
|
bb0(%0 : $TestC):
|
|
%2 = ref_element_addr %0 : $TestC, #TestC.t
|
|
%3 = load_unowned %2 : $*@sil_unowned NSObject & TestP
|
|
return %3 : $NSObject & TestP
|
|
}
|
|
|
|
// CHECK-LABEL: define {{.*}}@test_load_take_unowned
|
|
// CHECK: [[REF:%.*]] = load ptr, ptr
|
|
// CHECK: swift_unownedRetainStrongAndRelease
|
|
// CHECK: [[EXIST0:%.*]] = insertvalue { ptr, ptr } undef, ptr [[REF]], 0
|
|
// CHECK: [[EXIST:%.*]] = insertvalue { ptr, ptr } [[EXIST0]], ptr {{.*}}, 1
|
|
// CHECK: ret { ptr, ptr } [[EXIST]]
|
|
|
|
sil @test_load_take_unowned : $@convention(method) (@guaranteed TestC) -> @owned NSObject & TestP {
|
|
bb0(%0 : $TestC):
|
|
%2 = ref_element_addr %0 : $TestC, #TestC.t
|
|
%3 = load_unowned [take] %2 : $*@sil_unowned NSObject & TestP
|
|
return %3 : $NSObject & TestP
|
|
}
|
|
|
|
sil_vtable TestC { }
|
|
|
|
sil_vtable NSObject { }
|