| // RUN: %empty-directory(%t) |
| // RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_struct.swiftmodule -module-name=resilient_struct %S/../Inputs/resilient_struct.swift |
| |
| // RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution %s -target %target-pre-stable-abi-triple | %FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-OLD --check-prefix=CHECK-%target-ptrsize --check-prefix=CHECK-OLD-%target-ptrsize -DINT=i%target-ptrsize |
| // RUN: %target-swift-frontend -I %t -emit-ir -enable-library-evolution -O %s -target %target-pre-stable-abi-triple |
| |
| // REQUIRES: objc_interop |
| // UNSUPPORTED: swift_only_stable_abi |
| |
| // With the old deployment target, these classes use the 'singleton' metadata |
| // initialization pattern. The class is not statically visible to Objective-C, |
| // and the Swift runtime adds the class using objc_readClassPair() once it |
| // has computed field offsets and so on. |
| // |
| // With the new deployment target, these classes use the 'update' metadata |
| // initialization pattern. These class *are* visible to Objective-C, and the |
| // Swift runtime realizes them using the new _objc_realizeClassFromSwift() |
| // entry point. |
| // |
| // See class_update_callback_without_fixed_layout_stable_abi.swift, which uses |
| // the same input file, for the stable ABI deployment target test. |
| |
| sil_stage canonical |
| |
| import Builtin |
| import Swift |
| import SwiftShims |
| |
| import resilient_struct |
| |
| public class ClassWithResilientField { |
| var first: Int |
| var second: Size |
| var third: Int |
| |
| init(x: Int, y: Size, z: Int) |
| } |
| |
| sil_vtable ClassWithResilientField {} |
| |
| public class SubclassOfClassWithResilientField : ClassWithResilientField {} |
| |
| sil_vtable SubclassOfClassWithResilientField {} |
| |
| |
| // Field offsets are not statically known: |
| // CHECK-32-DAG: @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldC5firstSivpWvd" = hidden constant i32 8 |
| // CHECK-64-DAG: @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldC5firstSivpWvd" = hidden constant i64 16 |
| // CHECK-DAG: @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldC6second16resilient_struct4SizeVvpWvd" = hidden global [[INT]] 0 |
| // CHECK-DAG: @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldC5thirdSivpWvd" = hidden global [[INT]] 0 |
| |
| |
| // RO-data for ClassWithResilientField: |
| // CHECK-LABEL: @_DATA__TtC42class_update_callback_without_fixed_layout23ClassWithResilientField = internal constant { |
| |
| // -- flags: compiled with ARC |
| // CHECK-OLD-SAME: i32 128, |
| |
| // -- flags: compiled with ARC, has update callback |
| // CHECK-NEW-SAME: i32 192, |
| |
| // -- the update callback |
| // CHECK-NEW-SAME: @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMU{{(\.ptrauth)?}}" |
| |
| // CHECK-SAME: }, section "__DATA, {{.*}}" |
| |
| // Class has static metadata: |
| // CHECK-LABEL: @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMf" |
| |
| |
| // Subclass also has static metadata: |
| // CHECK-LABEL: @"$s42class_update_callback_without_fixed_layout33SubclassOfClassWithResilientFieldCMf" = internal global <{{.*}}> <{ |
| |
| // Superclass field is filled in dynamically: |
| // CHECK-OLD-SAME: i8* null, |
| |
| // Superclass field is filled in statically: |
| // CHECK-NEW-SAME: @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMf" |
| |
| // CHECK-SAME: }> |
| |
| |
| enum EnumWithResilientPayload { |
| case none |
| case some(ClassWithResilientEnum) |
| case data(ResilientRef) |
| } |
| |
| public class ClassWithResilientEnum { |
| var first: EnumWithResilientPayload |
| var second: Int8 |
| |
| init(x: EnumWithResilientPayload, y: Int8) |
| } |
| |
| sil_vtable ClassWithResilientEnum {} |
| |
| |
| // Make sure extra inhabitants work when reading a legacy layout -- the |
| // Optional<ResilientRef> should be 8 bytes in size, not 9 |
| public class ClassWithResilientRef { |
| var first: ResilientRef? |
| var second: Int |
| } |
| |
| sil_vtable ClassWithResilientRef {} |
| |
| // Field offsets are not statically known: |
| // CHECK-DAG: @"$s42class_update_callback_without_fixed_layout21ClassWithResilientRefC5first16resilient_struct0iJ0VSgvpWvd" = hidden global [[INT]] 0 |
| // CHECK-DAG: @"$s42class_update_callback_without_fixed_layout21ClassWithResilientRefC6secondSivpWvd" = hidden global [[INT]] 0 |
| |
| |
| // When allocating a class with resiliently-sized fields, we must still load |
| // the size and alignment from metadata, because its metadata may have been |
| // re-initialized. |
| |
| // CHECK-LABEL: define {{(dllexport )?}}{{(protected )?}}swiftcc void @allocClassWithResilientField() |
| sil @allocClassWithResilientField : $@convention(thin) () -> () { |
| bb0: |
| |
| // CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMa"([[INT]] 0) |
| // CHECK-NEXT: [[META:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 |
| // CHECK-NEXT: [[META_ADDR:%.*]] = bitcast %swift.type* [[META]] to i8* |
| // CHECK-32-NEXT: [[SIZE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[META_ADDR]], i32 28 |
| // CHECK-64-NEXT: [[SIZE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[META_ADDR]], i32 48 |
| // CHECK-NEXT: [[SIZE_PTR:%.*]] = bitcast i8* [[SIZE_ADDR]] to i32* |
| // CHECK-32-NEXT: [[SIZE:%.*]] = load i32, i32* [[SIZE_PTR]] |
| // CHECK-64-NEXT: [[SIZE_2:%.*]] = load i32, i32* [[SIZE_PTR]] |
| // CHECK-64-NEXT: [[SIZE:%.*]] = zext i32 [[SIZE_2]] to i64 |
| // CHECK-32-NEXT: [[ALIGN_ADDR:%.*]] = getelementptr inbounds i8, i8* [[META_ADDR]], i32 32 |
| // CHECK-64-NEXT: [[ALIGN_ADDR:%.*]] = getelementptr inbounds i8, i8* [[META_ADDR]], i32 52 |
| // CHECK-NEXT: [[ALIGN_PTR:%.*]] = bitcast i8* [[ALIGN_ADDR]] to i16* |
| // CHECK-NEXT: [[ALIGN_2:%.*]] = load i16, i16* [[ALIGN_PTR]] |
| // CHECK-NEXT: [[ALIGN:%.*]] = zext i16 [[ALIGN_2]] to [[INT]] |
| // CHECK-NEXT: [[ALLOC:%.*]] = call noalias %swift.refcounted* @swift_allocObject(%swift.type* [[META]], [[INT]] [[SIZE]], [[INT]] [[ALIGN]]) |
| %c = alloc_ref $ClassWithResilientField |
| |
| // ... dealloc_ref also does the same thing. |
| |
| // CHECK-NEXT: [[SELF:%.*]] = bitcast %swift.refcounted* [[ALLOC]] to %T42class_update_callback_without_fixed_layout23ClassWithResilientFieldC* |
| // CHECK-NEXT: [[ISA_ADDR:%.*]] = getelementptr inbounds %T42class_update_callback_without_fixed_layout23ClassWithResilientFieldC, %T42class_update_callback_without_fixed_layout23ClassWithResilientFieldC* [[SELF]], i32 0, i32 0, i32 0 |
| // CHECK-NEXT: [[META:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]] |
| // CHECK-NEXT: [[META_ADDR:%.*]] = bitcast %swift.type* [[META]] to i8* |
| // CHECK-32-NEXT: [[SIZE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[META_ADDR]], i32 28 |
| // CHECK-64-NEXT: [[SIZE_ADDR:%.*]] = getelementptr inbounds i8, i8* [[META_ADDR]], i32 48 |
| // CHECK-NEXT: [[SIZE_PTR:%.*]] = bitcast i8* [[SIZE_ADDR]] to i32* |
| // CHECK-32-NEXT: [[SIZE:%.*]] = load i32, i32* [[SIZE_PTR]] |
| // CHECK-64-NEXT: [[SIZE_2:%.*]] = load i32, i32* [[SIZE_PTR]] |
| // CHECK-64-NEXT: [[SIZE:%.*]] = zext i32 [[SIZE_2]] to i64 |
| // CHECK-32-NEXT: [[ALIGN_ADDR:%.*]] = getelementptr inbounds i8, i8* [[META_ADDR]], i32 32 |
| // CHECK-64-NEXT: [[ALIGN_ADDR:%.*]] = getelementptr inbounds i8, i8* [[META_ADDR]], i32 52 |
| // CHECK-NEXT: [[ALIGN_PTR:%.*]] = bitcast i8* [[ALIGN_ADDR]] to i16* |
| // CHECK-NEXT: [[ALIGN_2:%.*]] = load i16, i16* [[ALIGN_PTR]] |
| // CHECK-NEXT: [[ALIGN:%.*]] = zext i16 [[ALIGN_2]] to [[INT]] |
| // CHECK-NEXT: [[ALLOC:%.*]] = bitcast %T42class_update_callback_without_fixed_layout23ClassWithResilientFieldC* [[SELF]] to %swift.refcounted* |
| // CHECK-NEXT: call void @swift_deallocClassInstance(%swift.refcounted* [[ALLOC]], [[INT]] [[SIZE]], [[INT]] [[ALIGN]]) |
| dealloc_ref %c : $ClassWithResilientField |
| |
| %result = tuple () |
| return %result : $() |
| } |
| |
| |
| // Metadata accessor for ClassWithResilientField uses singleton initialization: |
| |
| // CHECK-LABEL: define swiftcc %swift.metadata_response @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMa |
| |
| // CHECK: [[CACHE:%.*]] = load %swift.type*, %swift.type** getelementptr inbounds ({ %swift.type*, i8* }, { %swift.type*, i8* }* @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMl", i32 0, i32 0) |
| // CHECK-NEXT: [[COND:%.*]] = icmp eq %swift.type* [[CACHE]], null |
| // CHECK-NEXT: br i1 [[COND]], label %cacheIsNull, label %cont |
| |
| // CHECK: cacheIsNull: |
| // CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @swift_getSingletonMetadata([[INT]] %0, %swift.type_descriptor* bitcast ({{.*}} @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMn" to %swift.type_descriptor*)) |
| // CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0 |
| // CHECK-NEXT: [[STATUS:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 1 |
| // CHECK-NEXT: br label %cont |
| |
| // CHECK: cont: |
| // CHECK-NEXT: [[NEW_METADATA:%.*]] = phi %swift.type* [ [[CACHE]], %entry ], [ [[METADATA]], %cacheIsNull ] |
| // CHECK-NEXT: [[NEW_STATUS:%.*]] = phi [[INT]] [ 0, %entry ], [ [[STATUS]], %cacheIsNull ] |
| // CHECK-NEXT: [[T0:%.*]] = insertvalue %swift.metadata_response undef, %swift.type* [[NEW_METADATA]], 0 |
| // CHECK-NEXT: [[T1:%.*]] = insertvalue %swift.metadata_response [[T0]], [[INT]] [[NEW_STATUS]], 1 |
| // CHECK-NEXT: ret %swift.metadata_response [[T1]] |
| |
| |
| // Accessing a field whose offset depends on resilient types should |
| // use the field offset global. |
| |
| // CHECK-32-LABEL: define swiftcc {{(dllexport )?}}{{(protected )?}}i32 @accessClassWithResilientField(%T42class_update_callback_without_fixed_layout23ClassWithResilientFieldC* %0) |
| // CHECK-64-LABEL: define swiftcc {{(dllexport )?}}{{(protected )?}}i64 @accessClassWithResilientField(%T42class_update_callback_without_fixed_layout23ClassWithResilientFieldC* %0) |
| sil @accessClassWithResilientField : $@convention(thin) (@guaranteed ClassWithResilientField) -> Int { |
| bb0(%0 : $ClassWithResilientField): |
| |
| // CHECK: [[OFFSET:%.*]] = load [[INT]], [[INT]]* @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldC5thirdSivpWvd" |
| // CHECK-NEXT: [[SELF_ADDR:%.*]] = bitcast %T42class_update_callback_without_fixed_layout23ClassWithResilientFieldC* %0 to i8* |
| // CHECK-NEXT: [[FIELD_ADDR:%.*]] = getelementptr inbounds i8, i8* [[SELF_ADDR]], [[INT]] [[OFFSET]] |
| // CHECK-NEXT: [[FIELD_PTR2:%.*]] = bitcast i8* [[FIELD_ADDR]] to %TSi* |
| // CHECK-NEXT: [[FIELD_PTR:%.*]] = getelementptr inbounds %TSi, %TSi* [[FIELD_PTR2]], i32 0, i32 0 |
| |
| %1 = ref_element_addr %0 : $ClassWithResilientField, #ClassWithResilientField.third |
| |
| // CHECK-NEXT: [[VALUE:%.*]] = load [[INT]], [[INT]]* [[FIELD_PTR]] |
| %2 = load %1 : $*Int |
| |
| // CHECK-NEXT: ret [[INT]] [[VALUE]] |
| return %2 : $Int |
| } |
| |
| |
| // Objective-C metadata update callback function for ClassWithResilientField: |
| |
| // CHECK-OLD-NOT: define internal %objc_class* @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMU"(%objc_class* %0, i8* %1) |
| |
| // CHECK-NEW-LABEL: define internal %objc_class* @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMU"(%objc_class* %0, i8* %1) |
| // CHECK-NEW: entry: |
| // CHECK-NEW-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMa"([[INT]] 0) |
| // CHECK-NEW-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0 |
| // CHECK-NEW-NEXT: [[RESULT:%.*]] = bitcast %swift.type* [[METADATA]] to %objc_class* |
| // CHECK-NEW-NEXT: ret %objc_class* [[RESULT]] |
| |
| |
| // Metadata initialization function for ClassWithResilientField calls swift_updateClassMetadata2() |
| // with the new deployment target: |
| |
| // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldCMr"(%swift.type* %0, i8* %1, i8** %2) |
| |
| // CHECK: entry: |
| // CHECK-NEXT: [[FIELDS:%.*]] = alloca [3 x i8**] |
| // CHECK-NEXT: [[METADATA_ADDR:%.*]] = bitcast %swift.type* %0 to [[INT]]* |
| // CHECK-32-NEXT: [[FIELDS_DEST:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_ADDR]], [[INT]] 13 |
| // CHECK-64-NEXT: [[FIELDS_DEST:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_ADDR]], [[INT]] 10 |
| // CHECK-NEXT: [[FIELDS_ADDR:%.*]] = bitcast [3 x i8**]* [[FIELDS]] to i8* |
| // CHECK-32-NEXT: call void @llvm.lifetime.start.p0i8(i64 12, i8* [[FIELDS_ADDR]]) |
| // CHECK-64-NEXT: call void @llvm.lifetime.start.p0i8(i64 24, i8* [[FIELDS_ADDR]]) |
| // CHECK-NEXT: [[FIELDS_PTR:%.*]] = getelementptr inbounds [3 x i8**], [3 x i8**]* [[FIELDS]], i32 0, i32 0 |
| |
| // CHECK: [[T0:%.*]] = call swiftcc %swift.metadata_response @"$s16resilient_struct4SizeVMa"([[INT]] 319) |
| // CHECK-NEXT: [[SIZE_METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 |
| // CHECK-NEXT: [[STATUS:%.*]] = extractvalue %swift.metadata_response [[T0]], 1 |
| // CHECK-NEXT: [[RESULT:%.*]] = icmp ule [[INT]] [[STATUS]], 63 |
| // CHECK-NEXT: br i1 [[RESULT]], label %dependency-satisfied, label %metadata-dependencies.cont |
| |
| // CHECK: dependency-satisfied: |
| |
| // -- ClassLayoutFlags = 0x100 (HasStaticVTable) |
| // CHECK-OLD: [[T0:%.*]] = call swiftcc %swift.metadata_response @swift_initClassMetadata2(%swift.type* %0, [[INT]] 256, [[INT]] 3, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]]) |
| // CHECK-NEW: [[T0:%.*]] = call swiftcc %swift.metadata_response @swift_updateClassMetadata2(%swift.type* %0, [[INT]] 256, [[INT]] 3, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]]) |
| // CHECK-NEXT: [[INITDEP_METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 |
| // CHECK-NEXT: [[INITDEP_STATUS:%.*]] = extractvalue %swift.metadata_response [[T0]], 1 |
| // CHECK-NEXT: [[INITDEP_PRESENT:%.*]] = icmp eq %swift.type* [[INITDEP_METADATA]], null |
| // CHECK-NEXT: br i1 [[INITDEP_PRESENT]], label %dependency-satisfied1, label %metadata-dependencies.cont |
| |
| // CHECK: dependency-satisfied1: |
| |
| // CHECK-native: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* {{.*}} |
| // CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldC1s16resilient_struct4SizeVvpWvd" |
| |
| // CHECK-native: [[FIELD_OFFSET:%.*]] = load [[INT]], [[INT]]* {{.*}} |
| // CHECK-native-NEXT: store [[INT]] [[FIELD_OFFSET]], [[INT]]* @"$s42class_update_callback_without_fixed_layout23ClassWithResilientFieldC5colors5Int32VvpWvd" |
| |
| // CHECK: br label %metadata-dependencies.cont |
| |
| // CHECK: metadata-dependencies.cont: |
| |
| // CHECK-NEXT: [[PENDING_METADATA:%.*]] = phi %swift.type* [ [[SIZE_METADATA]], %entry ], [ [[INITDEP_METADATA]], %dependency-satisfied ], [ null, %dependency-satisfied1 ] |
| // CHECK-NEXT: [[NEW_STATUS:%.*]] = phi [[INT]] [ 63, %entry ], [ [[INITDEP_STATUS]], %dependency-satisfied ], [ 0, %dependency-satisfied1 ] |
| // CHECK-NEXT: [[T0:%.*]] = insertvalue %swift.metadata_response undef, %swift.type* [[PENDING_METADATA]], 0 |
| // CHECK-NEXT: [[T1:%.*]] = insertvalue %swift.metadata_response [[T0]], [[INT]] [[NEW_STATUS]], 1 |
| // CHECK-NEXT: ret %swift.metadata_response [[T1]] |
| |
| |
| // Metadata initialization function for SubclassOfClassWithResilientField: |
| |
| // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s42class_update_callback_without_fixed_layout33SubclassOfClassWithResilientFieldCMr"(%swift.type* %0, i8* %1, i8** %2) |
| |
| // CHECK: entry: |
| // CHECK-NEXT: [[FIELDS:%.*]] = alloca [0 x i8**] |
| // CHECK-NEXT: [[METADATA_ADDR:%.*]] = bitcast %swift.type* %0 to [[INT]]* |
| // CHECK-32-NEXT: [[FIELDS_DEST:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_ADDR]], [[INT]] 17 |
| // CHECK-64-NEXT: [[FIELDS_DEST:%.*]] = getelementptr inbounds [[INT]], [[INT]]* [[METADATA_ADDR]], [[INT]] 14 |
| // CHECK-NEXT: [[FIELDS_ADDR:%.*]] = bitcast [0 x i8**]* [[FIELDS]] to i8* |
| // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 0, i8* [[FIELDS_ADDR]]) |
| // CHECK-NEXT: [[FIELDS_PTR:%.*]] = getelementptr inbounds [0 x i8**], [0 x i8**]* [[FIELDS]], i32 0, i32 0 |
| |
| // -- ClassLayoutFlags = 0x100 (HasStaticVTable) |
| // CHECK-OLD: [[T0:%.*]] = call swiftcc %swift.metadata_response @swift_initClassMetadata2(%swift.type* %0, [[INT]] 256, [[INT]] 0, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]]) |
| // CHECK-NEW: [[T0:%.*]] = call swiftcc %swift.metadata_response @swift_updateClassMetadata2(%swift.type* %0, [[INT]] 256, [[INT]] 0, i8*** [[FIELDS_PTR]], [[INT]]* [[FIELDS_DEST]]) |
| // CHECK-NEXT: [[INITDEP_METADATA:%.*]] = extractvalue %swift.metadata_response [[T0]], 0 |
| // CHECK-NEXT: [[INITDEP_STATUS:%.*]] = extractvalue %swift.metadata_response [[T0]], 1 |
| // CHECK-NEXT: [[INITDEP_PRESENT:%.*]] = icmp eq %swift.type* [[INITDEP_METADATA]], null |
| // CHECK-NEXT: br i1 [[INITDEP_PRESENT]], label %dependency-satisfied, label %metadata-dependencies.cont |
| |
| // CHECK: dependency-satisfied: |
| // CHECK: br label %metadata-dependencies.cont |
| |
| // CHECK: metadata-dependencies.cont: |
| // CHECK-NEXT: [[PENDING_METADATA:%.*]] = phi %swift.type* [ [[INITDEP_METADATA]], %entry ], [ null, %dependency-satisfied ] |
| // CHECK-NEXT: [[NEW_STATUS:%.*]] = phi [[INT]] [ [[INITDEP_STATUS]], %entry ], [ 0, %dependency-satisfied ] |
| // CHECK-NEXT: [[T0:%.*]] = insertvalue %swift.metadata_response undef, %swift.type* [[PENDING_METADATA]], 0 |
| // CHECK-NEXT: [[T1:%.*]] = insertvalue %swift.metadata_response [[T0]], [[INT]] [[NEW_STATUS]], 1 |
| // CHECK-NEXT: ret %swift.metadata_response [[T1]] |
| |
| // Metadata accessor for ClassWithResilientEnum looks like singleton initialization: |
| |
| // CHECK-LABEL: define swiftcc %swift.metadata_response @"$s42class_update_callback_without_fixed_layout22ClassWithResilientEnumCMa |
| |
| // CHECK: [[CACHE:%.*]] = load %swift.type*, %swift.type** getelementptr inbounds ({ %swift.type*, i8* }, { %swift.type*, i8* }* @"$s42class_update_callback_without_fixed_layout22ClassWithResilientEnumCMl", i32 0, i32 0) |
| // CHECK-NEXT: [[COND:%.*]] = icmp eq %swift.type* [[CACHE]], null |
| // CHECK-NEXT: br i1 [[COND]], label %cacheIsNull, label %cont |
| |
| // CHECK: cacheIsNull: |
| // CHECK-NEXT: [[RESPONSE:%.*]] = call swiftcc %swift.metadata_response @swift_getSingletonMetadata([[INT]] %0, %swift.type_descriptor* bitcast ({{.*}} @"$s42class_update_callback_without_fixed_layout22ClassWithResilientEnumCMn" to %swift.type_descriptor*)) |
| // CHECK-NEXT: [[METADATA:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 0 |
| // CHECK-NEXT: [[STATUS:%.*]] = extractvalue %swift.metadata_response [[RESPONSE]], 1 |
| // CHECK-NEXT: br label %cont |
| |
| // CHECK: cont: |
| // CHECK-NEXT: [[NEW_METADATA:%.*]] = phi %swift.type* [ [[CACHE]], %entry ], [ [[METADATA]], %cacheIsNull ] |
| // CHECK-NEXT: [[NEW_STATUS:%.*]] = phi [[INT]] [ 0, %entry ], [ [[STATUS]], %cacheIsNull ] |
| // CHECK-NEXT: [[T0:%.*]] = insertvalue %swift.metadata_response undef, %swift.type* [[NEW_METADATA]], 0 |
| // CHECK-NEXT: [[T1:%.*]] = insertvalue %swift.metadata_response [[T0]], [[INT]] [[NEW_STATUS]], 1 |
| // CHECK-NEXT: ret %swift.metadata_response [[T1]] |
| |
| // Make sure we cache the construction of fully bound optional types. |
| |
| // CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s42class_update_callback_without_fixed_layout21ClassWithResilientRefCMr" |
| // CHECK: call swiftcc %swift.metadata_response @"$s16resilient_struct12ResilientRefVSgMa" |
| // CHECK: ret |
| |
| // CHECK-LABEL: define linkonce_odr hidden swiftcc %swift.metadata_response @"$s16resilient_struct12ResilientRefVSgMa" |
| // CHECK: call swiftcc %swift.metadata_response @"$s16resilient_struct12ResilientRefVMa" |
| // CHECK: call swiftcc %swift.metadata_response @"$sSqMa" |
| // CHECK: ret |