// 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 { associatedtype T } sil @keep_alive : $@convention(thin)(@inout any Constrained) -> () sil @constrained_protocol : $@convention(thin) (@inout any Constrained) -> () { entry(%arg : $*any Constrained): %dst = alloc_stack $any Constrained copy_addr %arg to [init] %dst : $*any Constrained %fn = function_ref @keep_alive : $@convention(thin)(@inout any Constrained) -> () apply %fn(%dst) : $@convention(thin)(@inout any Constrained) -> () destroy_addr %dst : $*any Constrained dealloc_stack %dst : $*any Constrained %t = tuple () return %t : $() } // Make sure we don't instantiate metadata for constrained existentials. Metadata // instantiation 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