// RUN: %target-swift-emit-irgen -Onone \ // RUN: %s \ // RUN: | \ // RUN: %IRGenFileCheck %s @_silgen_name("external_symbol") func external_symbol() public protocol P { static func foo() } public class C { deinit { external_symbol() } } public struct InnerDeinitingReleasableNC : ~Copyable { public let i1: Int public let i2: Int public let i3: Int public let i4: Int public let c1: C public let c2: C public let c3: C public let c4: C deinit { external_symbol() } } public struct InnerDeinitingDestructableNC : ~Copyable { public let t: T public let i1: Int public let i2: Int public let i3: Int public let i4: Int public let c1: C public let c2: C public let c3: C public let c4: C deinit { external_symbol() } } public struct InnerDeinitingWithLayoutNC : ~Copyable { public let t: T deinit {} } public struct InnerDeinitingWithoutLayoutNC: ~Copyable { public let ptr: Int deinit {} } public struct OuterDeinitingNC_1 : ~Copyable { public let i1: Int public let c1: C public let i: InnerDeinitingReleasableNC deinit { external_symbol() } } public struct OuterNC_1 : ~Copyable { public let i1: Int public let c1: C public let i: InnerDeinitingReleasableNC } public struct OuterNC_2 : ~Copyable { public let i1: Int public let c1: C public let i: InnerDeinitingDestructableNC } public struct GenericContext_1 { } extension GenericContext_1 : P where T : P { public static func foo() { T.foo() } public struct OuterNC_1: ~Copyable { let i: Inner_NC1 func doit() { i.beinit() } } public struct Inner_NC1: ~Copyable { let t: T let ptr: Int deinit { T.foo() } func beinit() {} } } public enum OuterSinglePayloadNC_1: ~Copyable { case none case some(InnerDeinitingWithoutLayoutNC) } public enum OuterSinglePayloadNC_2: ~Copyable { case none case some(InnerDeinitingReleasableNC) } public enum OuterSinglePayloadNC_3: ~Copyable { case none case some(InnerDeinitingDestructableNC) } public enum OuterMultiPayloadNC_1: ~Copyable { case none case some(InnerDeinitingWithLayoutNC) case some2(InnerDeinitingWithLayoutNC) } public enum OuterMultiPayloadNC_2: ~Copyable { case none case some(InnerDeinitingWithoutLayoutNC) case some2(InnerDeinitingWithoutLayoutNC) } public enum OuterMultiPayloadNC_3: ~Copyable { case none case some(InnerDeinitingReleasableNC) case some2(InnerDeinitingReleasableNC) } public enum OuterMultiPayloadNC_4: ~Copyable { case none case some(InnerDeinitingDestructableNC) case some2(InnerDeinitingDestructableNC) } // Destroyed value: // - has deinit // On lifetime end: // - call deinit // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone22takeOuterDeinitingNC_1yyAA0fgH2_1VyxGnlF"( // CHECK-SAME: ptr{{.*}} %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: [[RESPONSE:%[^,]+]] = call{{.*}} @"$s30moveonly_value_functions_onone18OuterDeinitingNC_1VMa"( // : i64 0, // CHECK-SAME: ptr %T) // CHECK: [[OUTER_DEINITING_NC_1_METADATA:%[^,]+]] = extractvalue %swift.metadata_response [[RESPONSE]] // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone18OuterDeinitingNC_1VfD"( // CHECK-SAME: ptr [[OUTER_DEINITING_NC_1_METADATA]], // : ptr{{.*}} %t) // CHECK: } public func takeOuterDeinitingNC_1(_ t: consuming OuterDeinitingNC_1) { external_symbol() } // If the destroyed value has no deinit, is releasable, and contains a // noncopyable value with a deinit, call the outlined release function. // Destroyed value: // - has NO deinit // - contains value type with deinit // - is releasable // On lifetime end: // - call outlined release function // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone13takeOuterNC_1yyAA0fG2_1VyxGnlF"( // CHECK-SAME: ptr{{.*}} %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone9OuterNC_1VyxGlWOh"( // : ptr %o, // CHECK-SAME: ptr %T) // CHECK: } // Verify that the outlined release function takes the metadata for the // move-only-with-deinit type InnerDeinitingReleasableNC and passes it along // to that deinit. // $s30moveonly_value_functions_onone9OuterNC_1VyxGlWOs ---> outlined release of moveonly_value_functions.OuterNC_2 // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone9OuterNC_1VyxGlWOh"( // CHECK-SAME: ptr %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // ... // ... // CHECK: [[RESPONSE:%[^,]+]] = call{{.*}} @"$s30moveonly_value_functions_onone26InnerDeinitingReleasableNCVMa"( // : i64 0, // CHECK-SAME: ptr %T) // CHECK: [[INNER_DEINITING_RELEASABLE_NC_METADATA:%[^,]+]] = extractvalue %swift.metadata_response [[RESPONSE]] // CHECK: call swiftcc void @"$s30moveonly_value_functions_onone26InnerDeinitingReleasableNCVfD"( // CHECK-SAME: ptr [[INNER_DEINITING_RELEASABLE_NC_METADATA]], // : ptr noalias{{( nocapture)?}} swiftself{{( captures\(none\))?}} dereferenceable(64) %deinit.arg) // CHECK: } public func takeOuterNC_1(_ o: consuming OuterNC_1) { external_symbol() } // If the destroyed value has no deinit, is releasable, and contains a // noncopyable value with a deinit, call the outlined destroy function. // Destroyed value: // - has NO deinit // - contains value type with deinit // - is NOT releasable // On lifetime end: // - call outlined destroy destroy // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone13takeOuterNC_2yyAA0fG2_2VyxGnlF"( // CHECK-SAME: ptr{{.*}} %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone9OuterNC_2VyxGlWOh"( // : ptr %5, // CHECK-SAME: ptr %T) // CHECK: } // Verify that the outlined destroy function takes the metadata for the // move-only-with-deinit type InnerDeinitingDestructable and passes it along // to that deinit. // $s30moveonly_value_functions_onone9OuterNC_2VyxGlWOh ---> outlined destroy of moveonly_value_functions.OuterNC_2 // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone9OuterNC_2VyxGlWOh"( // CHECK-SAME: ptr %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // ... // ... // CHECK: [[RESPONSE:%[^,]+]] = call{{.*}} @"$s30moveonly_value_functions_onone28InnerDeinitingDestructableNCVMa"( // : i64 0, // CHECK-SAME: ptr %T) // CHECK: [[INNER_DEINITING_DESTRUCTABLE_NC_METADATA:%[^,]+]] = extractvalue %swift.metadata_response [[RESPONSE]] // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone28InnerDeinitingDestructableNCVfD"( // CHECK-SAME: ptr [[INNER_DEINITING_DESTRUCTABLE_NC_METADATA]], // : ptr noalias swiftself %3) // CHECK: } public func takeOuterNC_2(_ o: consuming OuterNC_2) { external_symbol() } // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone29takeGenericContext_1OuterNC_1yyAA0fG2_1VA2A1PRzlE0hI2_1Vyx_GnAaERzlF"( // CHECK-SAME: ptr noalias %0, // CHECK-SAME: ptr %T, // CHECK-SAME: ptr %T.P) // CHECK-SAME: { // CHECK: call ptr @"$s30moveonly_value_functions_onone16GenericContext_1VA2A1PRzlE9OuterNC_1Vyx_GAaDRzlWOh"( // : ptr %5, // CHECK-SAME: ptr %T, // CHECK-SAME: ptr %T.P) // CHECK: } // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone16GenericContext_1VA2A1PRzlE9OuterNC_1Vyx_GAaDRzlWOh"( // CHECK-SAME: ptr %0, // CHECK-SAME: ptr %T, // CHECK-SAME: ptr %T.P) // CHECK-SAME: { // CHECK: [[RESPONSE:%[^,]+]] = call{{.*}} @"$s30moveonly_value_functions_onone16GenericContext_1VA2A1PRzlE9Inner_NC1VMa"( // : i64 0, // CHECK-SAME: ptr %T, // CHECK-SAME: ptr %T.P) // CHECK: [[GENERIC_CONTEXT_1_INNER_NC_1_METADATA:%[^,]+]] = extractvalue %swift.metadata_response [[RESPONSE]], 0 // CHECK: call swiftcc void @"$s30moveonly_value_functions_onone16GenericContext_1VA2A1PRzlE9Inner_NC1VfD"( // CHECK-SAME: ptr [[GENERIC_CONTEXT_1_INNER_NC_1_METADATA]], // CHECK-SAME: ptr noalias swiftself %0) // CHECK: } public func takeGenericContext_1OuterNC_1(_ e: consuming GenericContext_1.OuterNC_1) {} // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone26takeOuterSinglePayloadNC_1yyAA0fghI2_1OyxGnlF"( // : i64 %0, // : i8 %1, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone22OuterSinglePayloadNC_1OyxGlWOh"( // : i64 %0, // : i1 %2, // CHECK-SAME: ptr %T) // CHECK: } // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone22OuterSinglePayloadNC_1OyxGlWOh"( // : i64 %0, // : i1 %1, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone29InnerDeinitingWithoutLayoutNCVfD"( // : i64 %0, // CHECK-SAME: ptr %T) // CHECK: } public func takeOuterSinglePayloadNC_1(_ e: consuming OuterSinglePayloadNC_1) {} // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone26takeOuterSinglePayloadNC_2yyAA0fghI2_2OyxGnlF"( // : ptr noalias {{(nocapture|captures\(none\))}} dereferenceable(64) %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone22OuterSinglePayloadNC_2OyxGlWOh"( // : ptr %0, // CHECK-SAME: ptr %T) // CHECK: } // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone22OuterSinglePayloadNC_2OyxGlWOh"( // CHECK-SAME: ptr %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: [[RESPONSE:%[^,]+]] = call swiftcc %swift.metadata_response @"$s30moveonly_value_functions_onone26InnerDeinitingReleasableNCVMa"( // : i64 0, // CHECK-SAME: ptr %T) // CHECK: [[METADATA:%[^,]+]] = extractvalue %swift.metadata_response [[RESPONSE]], 0 // CHECK: call swiftcc void @"$s30moveonly_value_functions_onone26InnerDeinitingReleasableNCVfD"( // CHECK-SAME: ptr [[METADATA]], // : ptr noalias{{( nocapture)?}} swiftself{{( captures\(none\))?}} dereferenceable(64) %0) // CHECK: } public func takeOuterSinglePayloadNC_2(_ e: consuming OuterSinglePayloadNC_2) {} // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone26takeOuterSinglePayloadNC_3yyAA0fghI2_3OyxGnlF"( // CHECK-SAME: ptr noalias %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone22OuterSinglePayloadNC_3OyxGlWOh"( // : ptr %0, // CHECK-SAME: ptr %T) // CHECK: } // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone22OuterSinglePayloadNC_3OyxGlWOh"( // CHECK-SAME: ptr %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: [[RESPONSE:%[^,]+]] = call{{.*}} @"$s30moveonly_value_functions_onone28InnerDeinitingDestructableNCVMa"( // : i64 0, // CHECK-SAME: ptr %T) // CHECK: [[METADATA:%[^,]+]] = extractvalue %swift.metadata_response [[RESPONSE:%[^,]+]], 0 // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone28InnerDeinitingDestructableNCVfD"( // CHECK-SAME: ptr [[METADATA:%[^,]+]], // : ptr noalias swiftself %0) // CHECK: } public func takeOuterSinglePayloadNC_3(_ e: consuming OuterSinglePayloadNC_3) {} // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone25takeOuterMultiPayloadNC_1yyAA0fghI2_1OyxGnlF"( // CHECK-SAME: ptr noalias %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone21OuterMultiPayloadNC_1OyxGlWOh"( // : ptr %5, // CHECK-SAME: ptr %T) // CHECK: } // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone21OuterMultiPayloadNC_1OyxGlWOh"( // CHECK-SAME: ptr %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: [[RESPONSE1:%[^,]+]] = call{{.*}} @"$s30moveonly_value_functions_onone26InnerDeinitingWithLayoutNCVMa"( // : i64 0, // CHECK-SAME: ptr %T) // CHECK: [[METADATA1:%[^,]+]] = extractvalue %swift.metadata_response [[RESPONSE1]], 0 // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone26InnerDeinitingWithLayoutNCVfD"( // CHECK-SAME: ptr [[METADATA1]], // CHECK-SAME: ptr noalias swiftself %0) // CHECK: [[RESPONSE2:%[^,]+]] = call{{.*}} @"$s30moveonly_value_functions_onone26InnerDeinitingWithLayoutNCVMa"( // : i64 0, // CHECK-SAME: ptr %T) // CHECK: [[METADATA2:%[^,]+]] = extractvalue %swift.metadata_response [[RESPONSE2]], 0 // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone26InnerDeinitingWithLayoutNCVfD"( // CHECK-SAME: ptr [[METADATA2]], // CHECK-SAME: ptr noalias swiftself %0) // CHECK: } public func takeOuterMultiPayloadNC_1(_ e: consuming OuterMultiPayloadNC_1) {} // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone25takeOuterMultiPayloadNC_2yyAA0fghI2_2OyxGnlF"( // : i64 %0, // : i8 %1, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone21OuterMultiPayloadNC_2OyxGlWOe"( // : i64 %0, // : i8 %1, // CHECK-SAME: ptr %T) // CHECK: } // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone21OuterMultiPayloadNC_2OyxGlWOe"( // : i64 %0, // : i8 %1, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone29InnerDeinitingWithoutLayoutNCVfD"( // : i64 %0, // CHECK-SAME: ptr %T) // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone29InnerDeinitingWithoutLayoutNCVfD"( // : i64 %0, // CHECK-SAME: ptr %T) // CHECK: } public func takeOuterMultiPayloadNC_2(_ e: consuming OuterMultiPayloadNC_2) {} // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone25takeOuterMultiPayloadNC_3yyAA0fghI2_3OyxGnlF"( // : ptr noalias {{(nocapture|captures\(none\))}} dereferenceable(64) %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone21OuterMultiPayloadNC_3OyxGlWOh"( // : ptr %e, // CHECK-SAME: ptr %T) // CHECK: } // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone21OuterMultiPayloadNC_3OyxGlWOh"( // CHECK-SAME: ptr %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone21OuterMultiPayloadNC_3OyxGlWOe"( // : i64 %2, // : i64 %4, // : i64 %6, // : i64 %8, // : i64 %10, // : i64 %12, // : i64 %14, // : i64 %16, // CHECK-SAME: ptr %T) // CHECK: } public func takeOuterMultiPayloadNC_3(_ e: consuming OuterMultiPayloadNC_3) {} // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone25takeOuterMultiPayloadNC_4yyAA0fghI2_4OyxGnlF"( // CHECK-SAME: ptr noalias %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone21OuterMultiPayloadNC_4OyxGlWOh"( // : ptr %5, // CHECK-SAME: ptr %T) // CHECK: } // CHECK-LABEL: define{{.*}} @"$s30moveonly_value_functions_onone21OuterMultiPayloadNC_4OyxGlWOh"( // CHECK-SAME: ptr %0, // CHECK-SAME: ptr %T) // CHECK-SAME: { // CHECK: [[RESPONSE1:%[^,]+]] = call{{.*}} @"$s30moveonly_value_functions_onone28InnerDeinitingDestructableNCVMa"( // : i64 0, // CHECK-SAME: ptr %T) // CHECK: [[METADATA1:%[^,]+]] = extractvalue %swift.metadata_response [[RESPONSE1]], 0 // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone28InnerDeinitingDestructableNCVfD"( // CHECK-SAME: ptr [[METADATA1]], // CHECK-SAME: ptr noalias swiftself %0) // CHECK: [[RESPONSE2:%[^,]+]] = call{{.*}} @"$s30moveonly_value_functions_onone28InnerDeinitingDestructableNCVMa"( // : i64 0, // CHECK-SAME: ptr %T) // CHECK: [[METADATA2:%[^,]+]] = extractvalue %swift.metadata_response [[RESPONSE2]], 0 // CHECK: call{{.*}} @"$s30moveonly_value_functions_onone28InnerDeinitingDestructableNCVfD"( // CHECK-SAME: ptr [[METADATA2]], // CHECK-SAME: ptr noalias swiftself %0) // CHECK: } public func takeOuterMultiPayloadNC_4(_ e: consuming OuterMultiPayloadNC_4) {}