blob: 10aceb8264b9330e23e2fc6a563c3a797501cb4d [file] [log] [blame]
// RUN: %target-swift-frontend -enable-type-layout -primary-file %s -emit-ir | %FileCheck %s --check-prefix=CHECK
// RUN: %target-swift-frontend -enable-type-layout -primary-file %s -O -emit-ir | %FileCheck %s --check-prefix=OPT --check-prefix=OPT-%target-ptrsize
// RUN: %target-swift-frontend -primary-file %s -emit-ir | %FileCheck %s --check-prefix=NOTL
public struct B<T> {
var x: T
var y: T
}
public struct A<T> {
var a : B<T>
var b: B<T>
}
// NOTL-LABEL: define{{.*}} %swift.opaque* @"$s30typelayout_based_value_witness1AVwCP"(
// NOTL: @"$s30typelayout_based_value_witness1BVMa"(
// NOTL: }
// CHECK-LABEL: define{{.*}} %swift.opaque* @"$s30typelayout_based_value_witness1AVwCP"(
// CHECK-NOT: @"$s30typelayout_based_value_witness1BVMa"(
// CHECK: }
// CHECK-LABEL: define{{.*}} void @"$s30typelayout_based_value_witness1AVwxx"(
// CHECK-NOT: @"$s30typelayout_based_value_witness1BVMa"
// CHECK: }
// CHECK-LABEL: define{{.*}} %swift.opaque* @"$s30typelayout_based_value_witness1AVwcp"(
// CHECK-NOT: @"$s30typelayout_based_value_witness1BVMa"
// CHECK: }
// CHECK-LABEL: define{{.*}} %swift.opaque* @"$s30typelayout_based_value_witness1AVwca"(
// CHECK-NOT: @"$s30typelayout_based_value_witness1BVMa"
// CHECK: }
// CHECK-LABEL: define{{.*}} %swift.opaque* @"$s30typelayout_based_value_witness1AVwtk"(
// CHECK-NOT: @"$s30typelayout_based_value_witness1BVMa"
// CHECK: }
// CHECK-LABEL: define{{.*}} %swift.opaque* @"$s30typelayout_based_value_witness1AVwta"(
// CHECK-NOT: @"$s30typelayout_based_value_witness1BVMa"
// CHECK: }
// CHECK-LABEL: define{{.*}} i32 @"$s30typelayout_based_value_witness1AVwet"(
// CHECK-NOT: @"$s30typelayout_based_value_witness1BVMa"
// CHECK: }
// CHECK-LABEL: define{{.*}} void @"$s30typelayout_based_value_witness1AVwst"(
// CHECK-NOT: @"$s30typelayout_based_value_witness1BVMa"
// CHECK: }
// OPT: define{{.*}} void @"$s30typelayout_based_value_witness1AVwxx"(%swift.opaque* noalias %object, %swift.type* nocapture readonly %"A<T>")
// OPT: [[T_PARAM:%.*]] = getelementptr inbounds %swift.type, %swift.type* %"A<T>", {{(i64|i32)}} 2
// OPT: [[T2:%.*]] = bitcast %swift.type* [[T_PARAM]] to %swift.type**
// OPT: [[T:%.*]] = load %swift.type*, %swift.type** [[T2]]
// OPT: [[VWT_ADDR:%.*]] = getelementptr inbounds %swift.type, %swift.type* [[T]], {{(i64|i32)}} -1
// OPT: [[VWT2:%.*]] = bitcast %swift.type* [[VWT_ADDR]] to i8***
// OPT: [[VWT:%.*]] = load i8**, i8*** [[VWT2]]
// OPT: [[DESTROY_VW:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], {{(i64|i32)}} 1
// OPT: [[DESTROY2:%.*]] = bitcast i8** [[DESTROY_VW]] to void (%swift.opaque*, %swift.type*)**
// OPT: [[DESTROY:%.*]] = load void (%swift.opaque*, %swift.type*)*, void (%swift.opaque*, %swift.type*)** [[DESTROY2]]
// OPT: tail call void [[DESTROY]](%swift.opaque* noalias %object, %swift.type* [[T]])
// OPT: [[SIZE_VW:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], {{(i64|i32)}} 8
// OPT: [[SIZE2:%.*]] = bitcast i8** [[SIZE_VW]] to {{(i64|i32)}}*
// OPT: [[SIZE_T:%.*]] = load {{(i64|i32)}}, {{(i64|i32)}}* [[SIZE2]]
// OPT: [[OBJECT:%.*]] = ptrtoint %swift.opaque* %object to {{(i64|i32)}}
// OPT: [[FLAGS_VW:%.*]] = getelementptr inbounds i8*, i8** [[VWT]], {{(i64|i32)}} 10
// OPT: [[FLAGS2:%.*]] = bitcast i8** [[FLAGS_VW]] to i32*
// OPT: [[FLAGS3:%.*]] = load i32, i32* [[FLAGS2]]
// OPT: [[FLAGS:%.*]] = and i32 [[FLAGS3]], 255
// OPT-64: %flags.alignmentMask = zext i32 [[FLAGS]] to i64
// OPT-64: [[TMP:%.*]] = add {{(i64|i32)}} [[SIZE_T]], %flags.alignmentMask
// OPT-32: [[TMP:%.*]] = add {{(i64|i32)}} %flags.alignmentMask, [[SIZE_T]]
// OPT: [[TMP2:%.*]] = add {{(i64|i32)}} [[TMP]], [[OBJECT]]
// OPT: [[INVERTED:%.*]] = xor {{(i64|i32)}} %flags.alignmentMask, -1
// OPT: [[ADDR2:%.*]] = and {{(i64|i32)}} [[TMP2:%.*]], [[INVERTED:%.*]]
// OPT: [[ADDR_T2:%.*]] = inttoptr {{(i64|i32)}} [[ADDR2]] to %swift.opaque*
// OPT: tail call void [[DESTROY]](%swift.opaque* noalias [[ADDR_T2]], %swift.type* [[T]])
// OPT: [[TMP3:%.*]] = and {{(i64|i32)}} [[TMP]], [[INVERTED:%.*]]
// OPT: [[TMP4:%.*]] = add {{(i64|i32)}} [[TMP2:%.*]], [[TMP3]]
// OPT: [[ADDR3:%.*]] = and {{(i64|i32)}} [[TMP4]], [[INVERTED:%.*]]
// OPT: [[ADDR_T3:%.*]] = inttoptr {{(i64|i32)}} [[ADDR3]] to %swift.opaque*
// OPT: tail call void [[DESTROY]](%swift.opaque* noalias [[ADDR_T3]], %swift.type* [[T]])
// OPT: [[TMP5:%.*]] = add {{(i64|i32)}} [[TMP]], [[ADDR3]]
// OPT: [[ADDR4:%.*]] = and {{(i64|i32)}} [[TMP5]], [[INVERTED:%.*]]
// OPT: [[ADDR_T4:%.*]] = inttoptr {{(i64|i32)}} [[ADDR4]] to %swift.opaque*
// OPT: tail call void [[DESTROY]](%swift.opaque* noalias [[ADDR_T4]], %swift.type* [[T]])
// OPT: ret void
// CHECK: }