Files
swift-mirror/test/IRGen/generic_classes.sil
T
John McCall 0ffb7278bc Only use metadata patterns for generic types; perform other
initialization in-place on demand.  Initialize parent metadata
references correctly on struct and enum metadata.

Also includes several minor improvements related to relative
pointers that I was using before deciding to simply switch the
parent reference to an absolute reference to get better access
patterns.

Includes a fix since the earlier commit to make enum metadata
writable if they have an unfilled payload size.  This didn't show
up on Darwin because "constant" is currently unenforced there in
global data containing relocations.

This patch requires an associated LLDB change which is being
submitted in parallel.
2016-03-24 15:10:31 -07:00

376 lines
18 KiB
Plaintext

// RUN: %target-swift-frontend %s -emit-ir | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%target-runtime
// REQUIRES: CPU=x86_64
import Builtin
import Swift
// CHECK: [[ROOTGENERIC:%C15generic_classes11RootGeneric]] = type <{ %swift.refcounted, %Vs5UInt8 }>
// -- offset of RootGeneric<T>.x
// FIXME: Strings should be unnamed_addr. rdar://problem/22674524
// CHECK: [[ROOTGENERIC_NAME:@.*]] = private constant [32 x i8] c"C15generic_classes11RootGeneric\00"
// CHECK: [[ROOTGENERIC_FIELDS:@.*]] = private constant [7 x i8] c"x\00y\00z\00\00"
// CHECK: @_TMnC15generic_classes11RootGeneric = {{(protected )?}}constant <{ {{.*}} i32 }> <{
// -- name
// CHECK: [32 x i8]* [[ROOTGENERIC_NAME]]
// -- num fields
// CHECK: i32 3,
// -- field offset vector offset
// CHECK: i32 15,
// -- field names
// CHECK: [7 x i8]* [[ROOTGENERIC_FIELDS]]
// -- generic metadata pattern
// CHECK: @_TMPC15generic_classes11RootGeneric
// -- generic parameter vector offset
// CHECK: i32 10,
// -- generic parameter count, primary count, witness table counts
// CHECK: i32 1, i32 1, i32 0
// CHECK: }
// CHECK: @_TMPC15generic_classes11RootGeneric = {{(protected )?}}global
// -- template fill function
// CHECK: %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_RootGeneric
// -- nominal type descriptor
// CHECK: @_TMnC15generic_classes11RootGeneric
// -- vtable
// CHECK: @_TFC15generic_classes11RootGeneric3fooU__fGS0_Q__FT_T_,
// CHECK: @_TFC15generic_classes11RootGeneric3barU__fGS0_Q__FT_T_,
// CHECK: @_TFC15generic_classes11RootGeneric3basU__fGS0_Q__FT_T_,
// -- field offset placeholders
// CHECK: i64 16, i64 0, i64 0
// CHECK: }>
// -- Check that offset vars are emitted for fixed-layout generics
// <rdar://problem/15081049>
// CHECK: @_TWvdvC15generic_classes22RootGenericFixedLayout1xVs5UInt8 = {{(protected )?}}constant i64 16, align 8
// CHECK: @_TWvdvC15generic_classes22RootGenericFixedLayout1yGSax_ = {{(protected )?}}constant i64 24, align 8
// CHECK: @_TWvdvC15generic_classes22RootGenericFixedLayout1zVs5UInt8 = {{(protected )?}}constant i64 32, align 8
// -- fixed-layout nongeneric descriptor
// FIXME: Strings should be unnamed_addr. rdar://problem/22674524
// CHECK: [[ROOTNONGENERIC_NAME:@.*]] = private constant [35 x i8] c"C15generic_classes14RootNonGeneric\00"
// CHECK: @_TMnC15generic_classes14RootNonGeneric = {{(protected )?}}constant <{ {{.*}} i32 }> <{
// -- name
// CHECK: [35 x i8]* [[ROOTNONGENERIC_NAME]]
// -- num fields
// CHECK: i32 3,
// -- -- field offset vector offset
// CHECK: i32 11,
// -- field names
// CHECK: [7 x i8]* [[ROOTGENERIC_FIELDS]]
// -- no generic metadata pattern, kind 0
// CHECK: i32 0,
// -- 0 = no generic parameter vector
// CHECK: i32 0,
// -- number of generic params, primary params
// CHECK: i32 0, i32 0
// CHECK: }>
// CHECK: @_TMfC15generic_classes14RootNonGeneric = internal global <{ {{.*}} }> <{
// CHECK: void (%C15generic_classes14RootNonGeneric*)* @_TFC15generic_classes14RootNonGenericD,
// CHECK: i8** @_TWVBo,
// CHECK-native: i64 0,
// CHECK-native: %swift.type* null,
// CHECK-native: %swift.opaque* null,
// CHECK-objc: i64 ptrtoint (%objc_class* @_TMmC15generic_classes14RootNonGeneric to i64),
// CHECK-objc: %objc_class* @"OBJC_CLASS_$_SwiftObject",
// CHECK-objc: %swift.opaque* @_objc_empty_cache,
// CHECK: %swift.opaque* null,
// CHECK-native: i64 1,
// CHECK-objc: @_DATA__TtC15generic_classes14RootNonGeneric
// CHECK: i32 33,
// CHECK: i16 7,
// CHECK: i16 0,
// CHECK: {{.*}}* @_TMnC15generic_classes14RootNonGeneric
// CHECK: }>
// CHECK: @_TMPC15generic_classes22GenericInheritsGeneric = {{(protected )?}}global
// -- template fill function
// CHECK: %swift.type* (%swift.type_pattern*, i8**)* @create_generic_metadata_GenericInheritsGeneric
// -- RootGeneric vtable
// CHECK: @_TFC15generic_classes11RootGeneric3fooU__fGS0_Q__FT_T_,
// CHECK: @_TFC15generic_classes11RootGeneric3barU__fGS0_Q__FT_T_,
// CHECK: @_TFC15generic_classes11RootGeneric3basU__fGS0_Q__FT_T_,
// -- RootGeneric field offset placeholders
// CHECK: i64 16, i64 0, i64 0
// -- GenericInheritsGeneric vtable
// CHECK: @_TFC15generic_classes22GenericInheritsGeneric7zippityU___fGS0_Q_Q0__FT_T_,
// CHECK: @_TFC15generic_classes22GenericInheritsGeneric3dooU___fGS0_Q_Q0__FT_T_,
// CHECK: @_TFC15generic_classes22GenericInheritsGeneric3dahU___fGS0_Q_Q0__FT_T_,
// -- GenericInheritsGeneric field offset placeholder
// CHECK: i64 0
// CHECK: }
// CHECK: @_TMPC15generic_classes25GenericInheritsNonGeneric
class RootGeneric<T> {
var x : UInt8
init()
// Test that declaration order doesn't cause the field offset vector to end
// up interleaved with the vtable.
func foo()
var y : T
func bar()
var z : UInt8
func bas()
}
sil @_TFC15generic_classes11RootGenericD : $@convention(method) <T> (RootGeneric<T>) -> ()
sil @_TFC15generic_classes11RootGeneric3fooU__fGS0_Q__FT_T_ : $@convention(method) <T> (@guaranteed RootGeneric<T>) -> ()
sil @_TFC15generic_classes11RootGeneric3barU__fGS0_Q__FT_T_ : $@convention(method) <T> (@guaranteed RootGeneric<T>) -> ()
sil @_TFC15generic_classes11RootGeneric3basU__fGS0_Q__FT_T_ : $@convention(method) <T> (@guaranteed RootGeneric<T>) -> ()
sil_vtable RootGeneric {
#RootGeneric.foo!1: _TFC15generic_classes11RootGeneric3fooU__fGS0_Q__FT_T_
#RootGeneric.bar!1: _TFC15generic_classes11RootGeneric3barU__fGS0_Q__FT_T_
#RootGeneric.bas!1: _TFC15generic_classes11RootGeneric3basU__fGS0_Q__FT_T_
}
class RootGenericFixedLayout<T> {
var x : UInt8
var y : [T]
var z : UInt8
init()
}
sil_vtable RootGenericFixedLayout {}
sil @_TFC15generic_classes22RootGenericFixedLayoutD : $@convention(method) <T> (RootGenericFixedLayout<T>) -> ()
class RootNonGeneric {
var x : UInt8
var y : Int
var z : UInt8
init()
}
sil_vtable RootNonGeneric {}
sil @_TFC15generic_classes14RootNonGenericD : $@convention(method) (RootNonGeneric) -> ()
class GenericInheritsGeneric<A, B> : RootGeneric<A> {
var w : B
func zippity()
func doo()
func dah()
override init()
}
sil @_TFC15generic_classes22GenericInheritsGenericD : $@convention(method) <T,U> (GenericInheritsGeneric<T,U>) -> ()
sil @_TFC15generic_classes22GenericInheritsGeneric7zippityU___fGS0_Q_Q0__FT_T_ : $@convention(method) <A, B> (@guaranteed GenericInheritsGeneric<A, B>) -> ()
sil @_TFC15generic_classes22GenericInheritsGeneric3dooU___fGS0_Q_Q0__FT_T_ : $@convention(method) <A, B> (@guaranteed GenericInheritsGeneric<A, B>) -> ()
sil @_TFC15generic_classes22GenericInheritsGeneric3dahU___fGS0_Q_Q0__FT_T_ : $@convention(method) <A, B> (@guaranteed GenericInheritsGeneric<A, B>) -> ()
sil_vtable GenericInheritsGeneric {
#RootGeneric.foo!1: _TFC15generic_classes11RootGeneric3fooU__fGS0_Q__FT_T_
#RootGeneric.bar!1: _TFC15generic_classes11RootGeneric3barU__fGS0_Q__FT_T_
#RootGeneric.bas!1: _TFC15generic_classes11RootGeneric3basU__fGS0_Q__FT_T_
#GenericInheritsGeneric.zippity!1: _TFC15generic_classes22GenericInheritsGeneric7zippityU___fGS0_Q_Q0__FT_T_
#GenericInheritsGeneric.doo!1: _TFC15generic_classes22GenericInheritsGeneric3dooU___fGS0_Q_Q0__FT_T_
#GenericInheritsGeneric.dah!1: _TFC15generic_classes22GenericInheritsGeneric3dahU___fGS0_Q_Q0__FT_T_
}
class GenericInheritsNonGeneric<C> : RootNonGeneric {
var w : UInt8
override init()
}
sil_vtable GenericInheritsNonGeneric {}
sil @_TFC15generic_classes25GenericInheritsNonGenericD : $@convention(method) <T> (GenericInheritsNonGeneric<T>) -> ()
// rdar://18067671
class RecursiveGenericInheritsGeneric<A, B> : RootGeneric<A> {
var w : B
var r : RecursiveGenericInheritsGeneric<A, B>?
func zippity()
func doo()
func dah()
override init()
}
sil_vtable RecursiveGenericInheritsGeneric {}
sil @_TFC15generic_classes31RecursiveGenericInheritsGenericD : $@convention(method) <T,U> (RecursiveGenericInheritsGeneric<T,U>) -> ()
// CHECK: define{{( protected)?}} [[ROOTGENERIC]]* @RootGeneric_fragile_dependent_alloc
// CHECK: [[METADATA:%.*]] = call %swift.type* @_TMaC15generic_classes11RootGeneric
// CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8*
// CHECK: [[T0:%.*]] = getelementptr inbounds i8, i8* [[METADATA_ARRAY]], i32 48
// CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i32*
// CHECK: [[SIZE32:%.*]] = load i32, i32* [[T1]], align 8
// CHECK: [[SIZE:%.*]] = zext i32 [[SIZE32]] to i64
// CHECK: [[T0:%.*]] = getelementptr inbounds i8, i8* [[METADATA_ARRAY]], i32 52
// CHECK: [[T1:%.*]] = bitcast i8* [[T0]] to i32*
// CHECK: [[ALIGN32:%.*]] = load i32, i32* [[T1]], align 4
// CHECK: [[ALIGN:%.*]] = zext i32 [[ALIGN32]] to i64
// CHECK: call noalias %swift.refcounted* @rt_swift_allocObject(%swift.type* [[METADATA]], i64 [[SIZE]], i64 [[ALIGN]])
sil @RootGeneric_fragile_dependent_alloc : $<G> () -> RootGeneric<G> {
entry:
%x = alloc_ref $RootGeneric<G>
return %x : $RootGeneric<G>
}
// RootGeneric.x has fixed layout
// CHECK: define{{( protected)?}} i8 @RootGeneric_concrete_fragile_dependent_member_access_x
// CHECK: getelementptr inbounds [[ROOTGENERIC]], [[ROOTGENERIC]]* %0, i32 0, i32 1
sil @RootGeneric_concrete_fragile_dependent_member_access_x : $<F> RootGeneric<F> -> UInt8 {
entry(%c : $RootGeneric<F>):
%p = ref_element_addr %c : $RootGeneric<F>, #RootGeneric.x
%x = load %p : $*UInt8
return %x : $UInt8
}
// RootGeneric.y has dependent layout; load the offset from the metadata
// CHECK-LABEL: define{{( protected)?}} void @RootGeneric_concrete_fragile_dependent_member_access_y
// CHECK: [[TYPE_METADATA_ARRAY:%.*]] = bitcast %swift.type* {{%.*}} to i64*
// CHECK: [[Y_OFFSET_ADDR:%.*]] = getelementptr inbounds i64, i64* [[TYPE_METADATA_ARRAY]], i64 16
// CHECK: [[Y_OFFSET:%.*]] = load i64, i64* [[Y_OFFSET_ADDR]], align 8
// CHECK: [[CLASS_BYTE_ARRAY:%.*]] = bitcast [[ROOTGENERIC]]* {{%.*}} to i8*
// CHECK: [[Y_ADDR:%.*]] = getelementptr inbounds i8, i8* [[CLASS_BYTE_ARRAY]], i64 [[Y_OFFSET]]
// CHECK: bitcast i8* [[Y_ADDR]] to %swift.opaque*
sil @RootGeneric_concrete_fragile_dependent_member_access_y : $<F> (RootGeneric<F>) -> @out F {
entry(%z : $*F, %c : $RootGeneric<F>):
%p = ref_element_addr %c : $RootGeneric<F>, #RootGeneric.y
copy_addr %p to [initialization] %z : $*F
%t = tuple ()
return %t : $()
}
// CHECK-LABEL: define{{( protected)?}} void @RootGeneric_subst_concrete_fragile_dependent_member_access_y
// CHECK: [[TYPE_METADATA_ARRAY:%.*]] = bitcast %swift.type* {{%.*}} to i64*
// CHECK: [[Y_OFFSET_ADDR:%.*]] = getelementptr inbounds i64, i64* [[TYPE_METADATA_ARRAY]], i64 16
// CHECK: [[Y_OFFSET:%.*]] = load i64, i64* [[Y_OFFSET_ADDR]], align 8
// CHECK: [[CLASS_BYTE_ARRAY:%.*]] = bitcast [[ROOTGENERIC]]* {{%.*}} to i8*
// CHECK: [[Y_ADDR:%.*]] = getelementptr inbounds i8, i8* [[CLASS_BYTE_ARRAY]], i64 [[Y_OFFSET]]
// CHECK: bitcast i8* [[Y_ADDR]] to %Si*
sil @RootGeneric_subst_concrete_fragile_dependent_member_access_y : $(RootGeneric<Int>) -> @out Int {
entry(%z : $*Int, %c : $RootGeneric<Int>):
%p = ref_element_addr %c : $RootGeneric<Int>, #RootGeneric.y
copy_addr %p to [initialization] %z : $*Int
%t = tuple ()
return %t : $()
}
// RootGeneric.z has dependent layout; load the offset from the metadata
// CHECK-LABEL: define{{( protected)?}} i8 @RootGeneric_concrete_fragile_dependent_member_access_z
// CHECK: [[TYPE_METADATA_ARRAY:%.*]] = bitcast %swift.type* {{%.*}} to i64*
// CHECK: [[Z_OFFSET_ADDR:%.*]] = getelementptr inbounds i64, i64* [[TYPE_METADATA_ARRAY]], i64 17
// CHECK: [[Z_OFFSET:%.*]] = load i64, i64* [[Z_OFFSET_ADDR]], align 8
// CHECK: [[CLASS_BYTE_ARRAY:%.*]] = bitcast [[ROOTGENERIC]]* {{%.*}} to i8*
// CHECK: [[Z_ADDR:%.*]] = getelementptr inbounds i8, i8* [[CLASS_BYTE_ARRAY]], i64 [[Z_OFFSET]]
// CHECK: bitcast i8* [[Z_ADDR]] to %Vs5UInt8*
sil @RootGeneric_concrete_fragile_dependent_member_access_z : $<F> RootGeneric<F> -> UInt8 {
entry(%c : $RootGeneric<F>):
%p = ref_element_addr %c : $RootGeneric<F>, #RootGeneric.z
%z = load %p : $*UInt8
return %z : $UInt8
}
// CHECK-LABEL: define{{( protected)?}} i8 @RootGeneric_subst_concrete_fragile_dependent_member_access_z
// CHECK: [[TYPE_METADATA_ARRAY:%.*]] = bitcast %swift.type* {{%.*}} to i64*
// CHECK: [[Z_OFFSET_ADDR:%.*]] = getelementptr inbounds i64, i64* [[TYPE_METADATA_ARRAY]], i64 17
// CHECK: [[Z_OFFSET:%.*]] = load i64, i64* [[Z_OFFSET_ADDR]], align 8
// CHECK: [[CLASS_BYTE_ARRAY:%.*]] = bitcast [[ROOTGENERIC]]* {{%.*}} to i8*
// CHECK: [[Z_ADDR:%.*]] = getelementptr inbounds i8, i8* [[CLASS_BYTE_ARRAY]], i64 [[Z_OFFSET]]
// CHECK: bitcast i8* [[Z_ADDR]] to %Vs5UInt8*
sil @RootGeneric_subst_concrete_fragile_dependent_member_access_z : $RootGeneric<Int> -> UInt8 {
entry(%c : $RootGeneric<Int>):
%p = ref_element_addr %c : $RootGeneric<Int>, #RootGeneric.z
%z = load %p : $*UInt8
return %z : $UInt8
}
/* TODO: Instantiate types for fragile generic instances so we can do
* fixed-layout access
sil @RootGeneric_concrete_fragile_fixed_member_access : $RootGeneric<Int32> -> (UInt8, Int32, UInt8) {
entry(%c : $RootGeneric<Int32>):
%p = ref_element_addr %c : $RootGeneric<Int32>, #RootGeneric.x
%x = load %p : $*UInt8
%q = ref_element_addr %c : $RootGeneric<Int32>, #RootGeneric.y
%y = load %q : $*Int32
%r = ref_element_addr %c : $RootGeneric<Int32>, #RootGeneric.z
%z = load %r : $*UInt8
%t = tuple (%x : $UInt8, %y : $Int32, %z : $UInt8)
return %t : $(UInt8, Int32, UInt8)
}
*/
// CHECK: define{{( protected)?}} private %swift.type* @create_generic_metadata_RootGeneric(%swift.type_pattern*, i8**) {{.*}} {
// -- initialize the dependent field offsets
// CHECK: call %swift.type* @swift_initClassMetadata_UniversalStrategy(%swift.type* {{%.*}}, i64 3, i64* {{%.*}}, i64* {{%.*}})
// CHECK: }
// CHECK: define{{( protected)?}} private %swift.type* @create_generic_metadata_RootGenericFixedLayout(%swift.type_pattern*, i8**) {{.*}} {
// CHECK: call %swift.type* @swift_initClassMetadata_UniversalStrategy(%swift.type* {{%.*}}, i64 3, i64* {{%.*}}, i64* {{%.*}})
// CHECK: }
// CHECK: define{{( protected)?}} private %swift.type* @create_generic_metadata_GenericInheritsGeneric(%swift.type_pattern*, i8**) {{.*}} {
// Bind the generic parameters.
// CHECK: [[T0:%.*]] = bitcast i8** %1 to %swift.type**
// CHECK: %A = load %swift.type*, %swift.type** [[T0]]
// CHECK: [[T1:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[T0]], i32 1
// CHECK: %B = load %swift.type*, %swift.type** [[T1]]
// Construct the superclass.
// CHECK: [[SUPER:%.*]] = call %swift.type* @_TMaC15generic_classes11RootGeneric(%swift.type* %A)
// CHECK: [[T0:%.*]] = bitcast %swift.type* [[SUPER]] to %objc_class*
// CHECK: [[METADATA:%.*]] = call %swift.type* @swift_allocateGenericClassMetadata(%swift.type_pattern* %0, i8** %1, %objc_class* [[T0]])
// CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
// Put the generic arguments in their correct positions.
// CHECK: [[A_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i32 18
// CHECK: [[T0:%.*]] = bitcast %swift.type* %A to i8*
// CHECK: store i8* [[T0]], i8** [[A_ADDR]], align 8
// CHECK: [[B_ADDR:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY:%.*]], i32 19
// CHECK: [[T0:%.*]] = bitcast %swift.type* %B to i8*
// CHECK: store i8* [[T0]], i8** [[B_ADDR]], align 8
// Set up the isa.
// CHECK-objc: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i8**
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 0
// CHECK-objc: [[T1:%.*]] = bitcast i8** [[T0]] to %objc_class**
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 25
// CHECK-objc: [[METACLASS:%.*]] = bitcast i8** [[T0]] to %objc_class*
// CHECK-objc: store %objc_class* [[METACLASS]], %objc_class** [[T1]], align 8
// Set up the instance rodata pointer.
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 4
// CHECK-objc: [[T1:%.*]] = bitcast i8** [[T0]] to i64*
// CHECK-objc: [[RODATA:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 30
// CHECK-objc: [[T2:%.*]] = ptrtoint i8** [[RODATA]] to i64
// CHECK-objc: [[T3:%.*]] = or i64 [[T2]], 1
// CHECK-objc: store i64 [[T3]], i64* [[T1]], align 8
// Set up the class rodata pointer.
// CHECK-objc: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 29
// CHECK-objc: [[T1:%.*]] = bitcast i8** [[T0]] to i64*
// CHECK-objc: [[META_RODATA:%.*]] = getelementptr inbounds i8*, i8** [[METADATA_ARRAY]], i32 39
// CHECK-objc: [[T2:%.*]] = ptrtoint i8** [[META_RODATA]] to i64
// CHECK-objc: store i64 [[T2]], i64* [[T1]], align 8
// Initialize our own dependent field offsets.
// CHECK: [[METADATA_ARRAY:%.*]] = bitcast %swift.type* [[METADATA]] to i64*
// CHECK: [[OFFSETS:%.*]] = getelementptr inbounds i64, i64* [[METADATA_ARRAY]], i32 23
// CHECK: [[T0:%.*]] = bitcast %swift.type* %B to i8***
// CHECK: [[T1:%.*]] = getelementptr inbounds i8**, i8*** [[T0]], i64 -1
// CHECK: [[VWT:%.*]] = load i8**, i8*** [[T1]], align 8
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 17
// CHECK: [[T1:%.*]] = load i8*, i8** [[T0]], align 8
// CHECK: [[SIZE:%.*]] = ptrtoint i8* [[T1]] to i64
// CHECK: [[T0:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], i32 18
// CHECK: [[T1:%.*]] = load i8*, i8** [[T0]], align 8
// CHECK: [[T2:%.*]] = ptrtoint i8* [[T1]] to i64
// CHECK: [[ALIGN:%.*]] = and i64 [[T2]], 65535
// CHECK: [[SIZE_ADDR:%.*]] = getelementptr inbounds [2 x i64], [2 x i64]* [[TYPES:%.*]], i32 0, i32 0
// CHECK: store i64 [[SIZE]], i64* [[SIZE_ADDR]], align 8
// CHECK: [[ALIGN_ADDR:%.*]] = getelementptr inbounds [2 x i64], [2 x i64]* [[TYPES]], i32 0, i32 1
// CHECK: store i64 [[ALIGN]], i64* [[ALIGN_ADDR]], align 8
// CHECK: call %swift.type* @swift_initClassMetadata_UniversalStrategy(%swift.type* [[METADATA]], i64 1, i64* [[SIZE_ADDR]], i64* [[OFFSETS]])
// CHECK: ret %swift.type* [[METADATA]]
// CHECK: }