mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
242 lines
10 KiB
Plaintext
242 lines
10 KiB
Plaintext
// RUN: %empty-directory(%t)
|
|
// RUN: %{python} %utils/chex.py < %s > %t/generic_structs_future.sil
|
|
// RUN: %target-swift-frontend -disable-type-layout -prespecialize-generic-metadata -target %module-target-future %t/generic_structs_future.sil -emit-ir | %FileCheck %t/generic_structs_future.sil
|
|
|
|
// REQUIRES: VENDOR=apple || OS=linux-gnu
|
|
// REQUIRES: CPU=x86_64
|
|
|
|
import Builtin
|
|
|
|
// -- Generic structs with fixed layout should have no completion function
|
|
// and emit the field offset vector as part of the pattern.
|
|
// CHECK: [[PATTERN:@.*]] = internal constant <{ i32, i32, i32, [4 x i8], i64 }> <{ i32 0, i32 1, i32 8, [4 x i8] zeroinitializer, i64 0 }>, align 8
|
|
// CHECK-LABEL: @"$s22generic_structs_future18FixedLayoutGenericVMP" = internal constant <{ {{.*}} }> <{
|
|
// -- instantiation function
|
|
// CHECK-SAME: ptr @"$s22generic_structs_future18FixedLayoutGenericVMi"
|
|
// -- completion function
|
|
// CHECK-SAME: i32 0,
|
|
// -- pattern flags
|
|
// CHECK-SAME: <i32 0x4000_0003>,
|
|
// -- vwtable pointer
|
|
// CHECK-SAME: @"$s22generic_structs_future18FixedLayoutGenericVWV"
|
|
// -- extra data pattern
|
|
// CHECK-SAME: ptr [[PATTERN]]
|
|
// CHECK-SAME: i16 1,
|
|
// CHECK-SAME: i16 3 }>
|
|
|
|
// -- Generic structs with dynamic layout contain the vwtable pattern as part
|
|
// of the metadata pattern, and no independent vwtable symbol
|
|
// CHECK: @"$s22generic_structs_future13SingleDynamicVWV" = internal constant
|
|
// CHECK-SAME: ptr @"$s22generic_structs_future13SingleDynamicVwCP",
|
|
// -- ...
|
|
// -- placeholder for size, stride, flags
|
|
// CHECK-SAME: i64 0,
|
|
// CHECK-SAME: i64 0,
|
|
// CHECK-SAME: i32 4194304,
|
|
// CHECK-SAME: i32 0 }
|
|
|
|
// FIXME: Strings should be unnamed_addr. rdar://problem/22674524
|
|
// CHECK: [[SINGLEDYNAMIC_NAME:@.*]] = private constant [14 x i8] c"SingleDynamic\00"
|
|
// CHECK: @"$s22generic_structs_future13SingleDynamicVMn" = hidden constant
|
|
// -- flags: struct, unique, generic
|
|
// CHECK-SAME: <i32 0x0000_00D1>
|
|
// -- name
|
|
// CHECK-SAME: ptr [[SINGLEDYNAMIC_NAME]]
|
|
// -- field count
|
|
// CHECK-SAME: i32 1,
|
|
// -- field offset vector offset
|
|
// CHECK-SAME: i32 3,
|
|
// -- generic instantiation info
|
|
// CHECK-SAME: ptr @"$s22generic_structs_future13SingleDynamicVMI"
|
|
// CHECK-SAME: @"$s22generic_structs_future13SingleDynamicVMP"
|
|
// -- generic params, requirements, key args, extra args
|
|
// CHECK-SAME: i16 1, i16 0, i16 1, i16 0
|
|
// -- generic parameters
|
|
// CHECK-SAME: <i8 0x80>
|
|
// CHECK-SAME: }>
|
|
// CHECK: @"$s22generic_structs_future13SingleDynamicVMP" = internal constant <{ {{.*}} }> <{
|
|
// -- instantiation function
|
|
// CHECK-SAME: ptr @"$s22generic_structs_future13SingleDynamicVMi"
|
|
// -- vwtable pointer
|
|
// CHECK-SAME: @"$s22generic_structs_future13SingleDynamicVWV"
|
|
|
|
// -- Nominal type descriptor for generic struct with protocol requirements
|
|
// FIXME: Strings should be unnamed_addr. rdar://problem/22674524
|
|
// CHECK: [[DYNAMICWITHREQUIREMENTS_NAME:@.*]] = private constant [24 x i8] c"DynamicWithRequirements\00"
|
|
// CHECK: @"$s22generic_structs_future23DynamicWithRequirementsVMn" = hidden constant <{ {{.*}} i32 }> <{
|
|
// -- flags: struct, unique, generic
|
|
// CHECK-SAME: <i32 0x0000_00D1>
|
|
// -- name
|
|
// CHECK-SAME: ptr [[DYNAMICWITHREQUIREMENTS_NAME]]
|
|
// -- field count
|
|
// CHECK-SAME: i32 2,
|
|
// -- field offset vector offset
|
|
// CHECK-SAME: i32 6,
|
|
// -- generic params, requirements, key args, extra args
|
|
// CHECK-SAME: i16 2, i16 2, i16 4, i16 0,
|
|
// -- generic parameters
|
|
// CHECK-SAME: <i8 0x80>, <i8 0x80>,
|
|
// -- generic requirement
|
|
// -- protocol requirement with key arg
|
|
// CHECK-SAME: i32 128
|
|
// -- param 0
|
|
// CHECK-SAME: i32 0
|
|
// -- protocol Req1
|
|
// CHECK-SAME: @"$s22generic_structs_future4Req1Mp"
|
|
|
|
// -- protocol requirement with key arg
|
|
// CHECK-SAME: i32 128
|
|
// -- param 1
|
|
// CHECK-SAME: i32 2
|
|
// -- protocol Req2
|
|
// CHECK-SAME: @"$s22generic_structs_future4Req2Mp"
|
|
// CHECK-SAME: }>
|
|
|
|
// CHECK: @"$s22generic_structs_future23DynamicWithRequirementsVMP" = internal constant <{ {{.*}} }> <{
|
|
|
|
// -- Fixed-layout struct metadata contains fixed field offsets
|
|
// CHECK: @"$s22generic_structs_future6IntishVMf" = internal constant <{ {{.*}} i32, [4 x i8], i64 }> <{
|
|
// CHECK-SAME: i32 0
|
|
// CHECK-SAME: }>
|
|
// CHECK: @"$s22generic_structs_future7CharethVMf" = internal constant <{ {{.*}} i32, [4 x i8], i64 }> <{
|
|
// CHECK-SAME: i32 0
|
|
// CHECK-SAME: }>
|
|
// CHECK: @"$s22generic_structs_future8StringlyVMf" = internal constant <{ {{.*}} i32, i32, i32, [4 x i8], i64 }> <{
|
|
// CHECK-SAME: i32 0, i32 8, i32 16, [4 x i8] zeroinitializer
|
|
// CHECK-SAME: }>
|
|
|
|
struct FixedLayoutGeneric<T> {
|
|
var x: Byteful
|
|
var y: Byteful
|
|
var z: Intish
|
|
}
|
|
|
|
struct SingleDynamic<T> {
|
|
var x : T
|
|
}
|
|
|
|
protocol Req1 { associatedtype Assoc1 }
|
|
protocol Req2 {}
|
|
|
|
struct DynamicWithRequirements<T: Req1, U: Req2> {
|
|
var x : T
|
|
var y : U
|
|
}
|
|
|
|
struct Intish { var value : Builtin.Int64 }
|
|
struct Chareth { var value : Builtin.Int21 }
|
|
struct Byteful { var value : Builtin.Int8 }
|
|
struct Stringly {
|
|
var owner : Builtin.NativeObject
|
|
var base : Builtin.RawPointer
|
|
var size : Builtin.Int64
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc { i64, i32 } @concrete_instances(i64 %0, i32 %1) {{.*}} {
|
|
// CHECK: entry:
|
|
// CHECK: %2 = trunc i32 %1 to i21
|
|
// CHECK: %3 = zext i21 %2 to i32
|
|
// CHECK: %4 = insertvalue { i64, i32 } undef, i64 %0, 0
|
|
// CHECK: %5 = insertvalue { i64, i32 } %4, i32 %3, 1
|
|
// CHECK: ret { i64, i32 } %5
|
|
// CHECK: }
|
|
sil @concrete_instances : $(SingleDynamic<Intish>, SingleDynamic<Chareth>) -> (Intish, Chareth) {
|
|
entry(%0 : $SingleDynamic<Intish>, %1 : $SingleDynamic<Chareth>):
|
|
%a = struct_extract %0 : $SingleDynamic<Intish>, #SingleDynamic.x
|
|
%b = struct_extract %1 : $SingleDynamic<Chareth>, #SingleDynamic.x
|
|
%c = tuple (%a : $Intish, %b : $Chareth)
|
|
return %c : $(Intish, Chareth)
|
|
}
|
|
|
|
struct ComplexDynamic<U, V> {
|
|
var a, a2 : Byteful
|
|
var b : U
|
|
var c : SingleDynamic<V>
|
|
var d : Chareth
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @explode_complex_dynamic
|
|
sil @explode_complex_dynamic : $<A, B> (@in ComplexDynamic<A, B>, @inout Byteful, @inout A, @inout B, @inout Chareth) -> () {
|
|
entry(%0 : $*ComplexDynamic<A, B>, %1 : $*Byteful, %2 : $*A, %3 : $*B, %4 : $*Chareth):
|
|
%a = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.a2
|
|
|
|
// CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, ptr {{%.*}}, i64 10
|
|
// CHECK: [[FIELD_OFFSET:%.*]] = load i32, ptr [[FIELD_OFFSET_ADDR]], align 8
|
|
// CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, ptr %0, i32 [[FIELD_OFFSET]]
|
|
%b = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.b
|
|
|
|
// CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, ptr {{%.*}}, i64 11
|
|
// CHECK: [[FIELD_OFFSET:%.*]] = load i32, ptr [[FIELD_OFFSET_ADDR]], align 8
|
|
// CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, ptr %0, i32 [[FIELD_OFFSET]]
|
|
%5 = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.c
|
|
%c = struct_element_addr %5 : $*SingleDynamic<B>, #SingleDynamic.x
|
|
|
|
// CHECK: [[FIELD_OFFSET_ADDR:%.*]] = getelementptr inbounds i32, ptr {{%.*}}, i64 12
|
|
// CHECK: [[FIELD_OFFSET:%.*]] = load i32, ptr [[FIELD_OFFSET_ADDR]], align 8
|
|
// CHECK: [[BYTE_OFFSET:%.*]] = getelementptr inbounds i8, ptr %0, i32 [[FIELD_OFFSET]]
|
|
%d = struct_element_addr %0 : $*ComplexDynamic<A, B>, #ComplexDynamic.d
|
|
copy_addr %a to %1 : $*Byteful
|
|
copy_addr %b to %2 : $*A
|
|
copy_addr %c to %3 : $*B
|
|
copy_addr %d to %4 : $*Chareth
|
|
%v = tuple ()
|
|
return %v : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( protected)?}} internal ptr @"$s22generic_structs_future13SingleDynamicVMi"(ptr %0, ptr %1, ptr %2)
|
|
// CHECK: %T = load ptr, ptr %1, align 8
|
|
// CHECK: [[METADATA:%.*]] = call ptr @swift_allocateGenericValueMetadata(ptr %0, ptr %1, ptr %2, i64 24)
|
|
// CHECK-NEXT: ret ptr [[METADATA]]
|
|
// CHECK: }
|
|
|
|
// CHECK-LABEL: define{{( protected)?}} internal swiftcc %swift.metadata_response @"$s22generic_structs_future13SingleDynamicVMr"
|
|
// CHECK-SAME: (ptr [[METADATA:%.*]], ptr %0, ptr %1) {{.*}} {
|
|
// Lay out fields.
|
|
// CHECK: [[T1:%.*]] = getelementptr inbounds i32, ptr [[METADATA]], i64 6
|
|
// CHECK: [[T2:%.*]] = getelementptr inbounds ptr, ptr [[TYPES:%.*]], i32 0
|
|
// CHECK: call void @swift_initStructMetadata(ptr [[METADATA]], i64 0, i64 1, ptr [[TYPES]], ptr [[T1]])
|
|
// CHECK: ret %swift.metadata_response
|
|
// CHECK: }
|
|
|
|
// Check that we directly delegate buffer witnesses to a single dynamic field:
|
|
|
|
// initializeBufferWithCopyOfBuffer
|
|
// CHECK-LABEL: define internal ptr @"$s22generic_structs_future13SingleDynamicVwCP"(ptr noalias %dest, ptr noalias %src, ptr %"SingleDynamic<T>") {{.*}} {
|
|
// CHECK: %T = load ptr,
|
|
// CHECK: [[T1:%.*]] = getelementptr inbounds ptr, ptr %T, i64 -1
|
|
// CHECK-NEXT: %T.valueWitnesses = load ptr, ptr [[T1]]
|
|
// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr %T.valueWitnesses,
|
|
// CHECK-NEXT: [[T0:%.*]] = call ptr [[T1]](ptr noalias %dest, ptr noalias %src, ptr %T)
|
|
// CHECK-NEXT: ret ptr [[T0]]
|
|
|
|
|
|
protocol HasAssociatedType {
|
|
associatedtype Assoc
|
|
}
|
|
protocol ParentHasAssociatedType : HasAssociatedType {
|
|
associatedtype Assoc : HasAssociatedType
|
|
}
|
|
|
|
struct GenericLayoutWithAssocType<T: ParentHasAssociatedType> {
|
|
var x: T.Assoc
|
|
var y: T.Assoc.Assoc
|
|
}
|
|
// CHECK-LABEL: define internal ptr @"$s22generic_structs_future26GenericLayoutWithAssocTypeVMi"(
|
|
// CHECK: %T = load ptr, ptr %1, align 8
|
|
// CHECK: [[T1:%.*]] = getelementptr inbounds ptr, ptr %1, i32 1
|
|
// CHECK: %T.ParentHasAssociatedType = load ptr, ptr [[T1]],
|
|
|
|
// CHECK: [[METADATA:%.*]] = call ptr @swift_allocateGenericValueMetadata
|
|
|
|
// CHECK-LABEL: define internal swiftcc %swift.metadata_response @"$s22generic_structs_future26GenericLayoutWithAssocTypeVMr"(
|
|
|
|
// CHECK: [[T0_GEP:%.*]] = getelementptr inbounds ptr, ptr %T.ParentHasAssociatedType, i32 1
|
|
// CHECK: [[T0:%.*]] = load ptr, ptr [[T0_GEP]]
|
|
// CHECK: [[T4:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness(i64 0, ptr %T.HasAssociatedType, ptr %T, ptr @"$s22generic_structs_future17HasAssociatedTypeTL", ptr @"$s5Assoc22generic_structs_future17HasAssociatedTypePTl")
|
|
|
|
// CHECK: %T.Assoc = extractvalue %swift.metadata_response [[T4]], 0
|
|
// CHECK: %T.Assoc.HasAssociatedType = call swiftcc ptr @swift_getAssociatedConformanceWitness(ptr %T.ParentHasAssociatedType, ptr %T, ptr %T.Assoc,
|
|
|
|
// CHECK: [[T2:%.*]] = call swiftcc %swift.metadata_response @swift_getAssociatedTypeWitness(i64 0, ptr %T.Assoc.HasAssociatedType, ptr %T.Assoc, ptr @"$s22generic_structs_future17HasAssociatedTypeTL", ptr @"$s5Assoc22generic_structs_future17HasAssociatedTypePTl")
|
|
// CHECK: %T.Assoc.Assoc = extractvalue %swift.metadata_response [[T2]], 0
|