Skip to content

Commit a5f0069

Browse files
committed
[metadata prespecialization] Check conformances.
Previously, the metadata accessor for a generic type for which some metadata prespecialization was done only tested that the type metadata arguments were equal to those of the prespecialization. If the generic type had an argument which was constrained to conform to a protocol, the particular conformance to that protocol was determined at compile time, but the conformance was ignored in the metadata accessor. As a result it was possible--in certain multi-module cases--for the metadata accessor to incorrectly return a prespecialized metadata record whose type arguments matched the type arguments passed to the accessor but whose conformance arguments did not. For example, given the following, Base: struct K {} protocol P {} Conformance1: import Base struct G<T : P> {} extension K : P {} // first conformance prespecialize( G<K>.self ) Conformance2: import Base extension K : P {} // second conformance the metadata accessor for G defined in Conformance1 would behave like MetadataResponse `metadata accessor for G`( MetadataRequest request, const Metadata *M, const WitnessTable *WT) { if (M == `type metadata for K`) { return `canonical prespecialized type metadata for G<K>` } return swift_getGenericMetadata(request, {M, WT}); } Here, the WitnessTable argument is the witness table describing a conformance of the type whose metadata is provided to the protocol P. The incorrect behavior occurs when calling the metadata accessor with these arguments: `some request` `type metadata for K` `protocol witness table for Base.K : Base.P in Conformance2` The accessor would return the `canonical prespecialized type metadata for G<K>`. The problem is that the prespecialized metadata contains the following generic arguments: `type metadata for K` `protocol witness table for Base.K : Base.P in Conformance1` Specificallly, the witness table is for the conformance from Conformance1, not the conformance from Conformance2. Here, the problem is addressed by testing that the witness tables passed into the accessor are for the same conformance as the witness table referred to by the prespecialized record. Now, the metadata accessor for G will behave like MetadataResponse `metadata accessor for G`( MetadataRequest request, const Metadata *M, const WitnessTable *WT) { if (M == `type metadata for K` swift_compareProtocolConformanceDescriptors( WT->getDescription(), `protocol conformance descriptor for Base.K : Base.P in Conformance1`) ) { return `canonical prespecialized type metadata for G<K>` } return swift_getGenericMetadata(request, {M, WT}); } Consequently, when the accessor is called with the same arguments as before, the call to swift_compareProtocolConformanceDescriptors will return false and the non-matching prespecialized metadata will not be returned.
1 parent 236237f commit a5f0069

9 files changed

+316
-16
lines changed

lib/IRGen/MetadataRequest.cpp

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1953,16 +1953,51 @@ static void emitCanonicalSpecializationsForGenericTypeMetadataAccessFunction(
19531953
auto requirements = GenericTypeRequirements(IGF.IGM, nominal);
19541954
int requirementIndex = 0;
19551955
for (auto requirement : requirements.getRequirements()) {
1956-
if (requirement.Protocol) {
1957-
continue;
1958-
}
19591956
auto parameter = requirement.TypeParameter;
19601957
auto argument = parameter.subst(substitutions);
1961-
llvm::Constant *addr =
1962-
IGM.getAddrOfTypeMetadata(argument->getCanonicalType());
1963-
auto addrInt = IGF.Builder.CreateBitCast(addr, IGM.Int8PtrTy);
1964-
condition = IGF.Builder.CreateAnd(
1965-
condition, IGF.Builder.CreateICmpEQ(addrInt, valueAtIndex(requirementIndex)));
1958+
if (requirement.Protocol) {
1959+
auto conformance = substitutions.lookupConformance(
1960+
requirement.TypeParameter->getCanonicalType(),
1961+
requirement.Protocol);
1962+
ProtocolConformance *concreteConformance = conformance.getConcrete();
1963+
auto argumentNominal = argument->getAnyNominal();
1964+
if (argumentNominal && argumentNominal->isGenericContext()) {
1965+
// TODO: Statically specialize the witness table pattern for t's
1966+
// conformance.
1967+
llvm_unreachable(
1968+
"Statically specializing metadata at generic types is "
1969+
"not supported.");
1970+
} else {
1971+
RootProtocolConformance *rootConformance =
1972+
concreteConformance->getRootConformance();
1973+
auto *expectedDescriptor =
1974+
IGF.IGM.getAddrOfProtocolConformanceDescriptor(rootConformance);
1975+
auto *witnessTable = valueAtIndex(requirementIndex);
1976+
auto *witnessBuffer =
1977+
IGF.Builder.CreateBitCast(witnessTable, IGM.Int8PtrPtrTy);
1978+
auto *uncastProvidedDescriptor =
1979+
IGF.Builder.CreateLoad(witnessBuffer, Alignment());
1980+
auto *providedDescriptor = IGF.Builder.CreateBitCast(
1981+
uncastProvidedDescriptor,
1982+
IGM.ProtocolConformanceDescriptorPtrTy);
1983+
1984+
auto *call = IGF.Builder.CreateCall(
1985+
IGF.IGM.getCompareProtocolConformanceDescriptorsFn(),
1986+
{providedDescriptor, expectedDescriptor});
1987+
call->setDoesNotThrow();
1988+
call->setCallingConv(IGF.IGM.SwiftCC);
1989+
call->addAttribute(llvm::AttributeList::FunctionIndex,
1990+
llvm::Attribute::ReadNone);
1991+
condition = IGF.Builder.CreateAnd(condition, call);
1992+
}
1993+
} else {
1994+
llvm::Constant *addr =
1995+
IGM.getAddrOfTypeMetadata(argument->getCanonicalType());
1996+
auto addrInt = IGF.Builder.CreateBitCast(addr, IGM.Int8PtrTy);
1997+
condition = IGF.Builder.CreateAnd(
1998+
condition, IGF.Builder.CreateICmpEQ(
1999+
addrInt, valueAtIndex(requirementIndex)));
2000+
}
19662001
++requirementIndex;
19672002
}
19682003
IGF.Builder.CreateCondBr(condition, specializationBlock, successorBlock);
@@ -2053,7 +2088,6 @@ MetadataResponse irgen::emitGenericTypeMetadataAccessFunction(
20532088
emitCanonicalSpecializationsForGenericTypeMetadataAccessFunction(
20542089
IGF, request, nominal, genericArgs, [&](int index) {
20552090
llvm::Value *indexValue = llvm::ConstantInt::get(IGM.Int64Ty, index);
2056-
llvm::SmallVector<llvm::Value *, 1> indices{indexValue};
20572091
llvm::Value *elementPointer =
20582092
IGF.Builder.CreateGEP(argumentsBuffer, indexValue);
20592093
llvm::LoadInst *retval = IGF.Builder.CreateLoad(

test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-1distinct_use.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,12 @@ doit()
7272
// CHECK: [[TYPE_COMPARISON_LABEL]]:
7373
// CHECK: [[EQUAL_TYPE:%[0-9]+]] = icmp eq i8* bitcast (%swift.type* @"$sSiN" to i8*), [[ERASED_TYPE]]
7474
// CHECK: [[EQUAL_TYPES:%[0-9]+]] = and i1 true, [[EQUAL_TYPE]]
75-
// CHECK: br i1 [[EQUAL_TYPES]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
75+
// CHECK: [[ARGUMENT_BUFFER:%[0-9]+]] = bitcast i8* [[ERASED_TABLE]] to i8**
76+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR:%[0-9]+]] = load i8*, i8** [[ARGUMENT_BUFFER]], align 1
77+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR]] to %swift.protocol_conformance_descriptor*
78+
// CHECK: [[EQUAL_DESCRIPTORS:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR]], %swift.protocol_conformance_descriptor* @"$sSi4main1PAAMc")
79+
// CHECK: [[EQUAL_ARGUMENTS:%[0-9]+]] = and i1 [[EQUAL_TYPES]], [[EQUAL_DESCRIPTORS]]
80+
// CHECK: br i1 [[EQUAL_ARGUMENTS]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
7681
// CHECK: [[EXIT_PRESPECIALIZED]]:
7782
// CHECK: ret %swift.metadata_response {
7883
// CHECK-SAME: %swift.type* getelementptr inbounds (

test/IRGen/prespecialized-metadata/enum-inmodule-1argument-1conformance-public-1distinct_use.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,12 @@ doit()
7272
// CHECK: [[TYPE_COMPARISON_LABEL]]:
7373
// CHECK: [[EQUAL_TYPE:%[0-9]+]] = icmp eq i8* bitcast (%swift.type* @"$sSiN" to i8*), [[ERASED_TYPE]]
7474
// CHECK: [[EQUAL_TYPES:%[0-9]+]] = and i1 true, [[EQUAL_TYPE]]
75-
// CHECK: br i1 [[EQUAL_TYPES]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
75+
// CHECK: [[ARGUMENT_BUFFER:%[0-9]+]] = bitcast i8* [[ERASED_TABLE]] to i8**
76+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR:%[0-9]+]] = load i8*, i8** [[ARGUMENT_BUFFER]], align 1
77+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR]] to %swift.protocol_conformance_descriptor*
78+
// CHECK: [[EQUAL_DESCRIPTORS:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR]], %swift.protocol_conformance_descriptor* @"$sSi4main1PAAMc")
79+
// CHECK: [[EQUAL_ARGUMENTS:%[0-9]+]] = and i1 [[EQUAL_TYPES]], [[EQUAL_DESCRIPTORS]]
80+
// CHECK: br i1 [[EQUAL_ARGUMENTS]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
7681
// CHECK: [[EXIT_PRESPECIALIZED]]:
7782
// CHECK: ret %swift.metadata_response {
7883
// CHECK-SAME: %swift.type* getelementptr inbounds (

test/IRGen/prespecialized-metadata/struct-inmodule-1argument-1conformance-1distinct_use.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,12 @@ doit()
5555
// CHECK: [[TYPE_COMPARISON_LABEL]]:
5656
// CHECK: [[EQUAL_TYPE:%[0-9]+]] = icmp eq i8* bitcast (%swift.type* @"$sSiN" to i8*), [[ERASED_TYPE]]
5757
// CHECK: [[EQUAL_TYPES:%[0-9]+]] = and i1 true, [[EQUAL_TYPE]]
58-
// CHECK: br i1 [[EQUAL_TYPES]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
58+
// CHECK: [[ARGUMENT_BUFFER:%[0-9]+]] = bitcast i8* [[ERASED_TABLE]] to i8**
59+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR:%[0-9]+]] = load i8*, i8** [[ARGUMENT_BUFFER]], align 1
60+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR]] to %swift.protocol_conformance_descriptor*
61+
// CHECK: [[EQUAL_DESCRIPTORS:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR]], %swift.protocol_conformance_descriptor* @"$sSi4main1PAAMc")
62+
// CHECK: [[EQUAL_ARGUMENTS:%[0-9]+]] = and i1 [[EQUAL_TYPES]], [[EQUAL_DESCRIPTORS]]
63+
// CHECK: br i1 [[EQUAL_ARGUMENTS]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
5964
// CHECK: [[EXIT_PRESPECIALIZED]]:
6065
// CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i8**, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 }
6166
// CHECK: [[EXIT_NORMAL]]:

test/IRGen/prespecialized-metadata/struct-inmodule-1argument-2conformance-1distinct_use.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,17 @@ doit()
6060
// CHECK: [[TYPE_COMPARISON_LABEL]]:
6161
// CHECK: [[EQUAL_TYPE:%[0-9]+]] = icmp eq i8* bitcast (%swift.type* @"$sSiN" to i8*), [[ERASED_TYPE]]
6262
// CHECK: [[EQUAL_TYPES:%[0-9]+]] = and i1 true, [[EQUAL_TYPE]]
63-
// CHECK: br i1 [[EQUAL_TYPES]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
63+
// CHECK: [[UNERASED_TABLE_1:%[0-9]+]] = bitcast i8* [[ERASED_TABLE_1]] to i8**
64+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_1:%[0-9]+]] = load i8*, i8** [[UNERASED_TABLE_1]], align 1
65+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR_1:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_1]] to %swift.protocol_conformance_descriptor*
66+
// CHECK: [[EQUAL_DESCRIPTORS_1:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR_1]], %swift.protocol_conformance_descriptor* @"$sSi4main1PAAMc")
67+
// CHECK: [[EQUAL_ARGUMENTS_1:%[0-9]+]] = and i1 [[EQUAL_TYPES]], [[EQUAL_DESCRIPTORS_1]]
68+
// CHECK: [[UNERASED_TABLE_2:%[0-9]+]] = bitcast i8* [[ERASED_TABLE_2]] to i8**
69+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_2:%[0-9]+]] = load i8*, i8** [[UNERASED_TABLE_2]], align 1
70+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR_2:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_2]] to %swift.protocol_conformance_descriptor*
71+
// CHECK: [[EQUAL_DESCRIPTORS_2:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR_2]], %swift.protocol_conformance_descriptor* @"$sSi4main1QAAMc")
72+
// CHECK: [[EQUAL_ARGUMENTS_2:%[0-9]+]] = and i1 [[EQUAL_ARGUMENTS_1]], [[EQUAL_DESCRIPTORS_2]]
73+
// CHECK: br i1 [[EQUAL_ARGUMENTS_2]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
6474
// CHECK: [[EXIT_PRESPECIALIZED]]:
6575
// CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i8**, i8**, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 }
6676
// CHECK: [[EXIT_NORMAL]]:

test/IRGen/prespecialized-metadata/struct-inmodule-1argument-3conformance-1distinct_use.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,28 @@ doit()
6464
// CHECK: %"load argument at index 0 from buffer" = load i8*, i8** [[ERASED_TYPE_ADDRESS]]
6565
// CHECK: [[EQUAL_TYPE:%[0-9]+]] = icmp eq i8* bitcast (%swift.type* @"$sSiN" to i8*), %"load argument at index 0 from buffer"
6666
// CHECK: [[EQUAL_TYPES:%[0-9]+]] = and i1 true, [[EQUAL_TYPE]]
67-
// CHECK: br i1 [[EQUAL_TYPES]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
67+
// CHECK: [[POINTER_TO_ERASED_TABLE_1:%[0-9]+]] = getelementptr i8*, i8** %1, i64 1
68+
// CHECK: [[ERASED_TABLE_1:%"load argument at index 1 from buffer"]] = load i8*, i8** [[POINTER_TO_ERASED_TABLE_1]], align 1
69+
// CHECK: [[UNERASED_TABLE_1:%[0-9]+]] = bitcast i8* [[ERASED_TABLE_1]] to i8**
70+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_1:%[0-9]+]] = load i8*, i8** [[UNERASED_TABLE_1]], align 1
71+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR_1:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_1]] to %swift.protocol_conformance_descriptor*
72+
// CHECK: [[EQUAL_DESCRIPTORS_1:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR_1]], %swift.protocol_conformance_descriptor* @"$sSi4main1PAAMc")
73+
// CHECK: [[EQUAL_ARGUMENTS_1:%[0-9]+]] = and i1 [[EQUAL_TYPES]], [[EQUAL_DESCRIPTORS_1]]
74+
// CHECK: [[POINTER_TO_ERASED_TABLE_2:%[0-9]+]] = getelementptr i8*, i8** %1, i64 2
75+
// CHECK: [[ERASED_TABLE_2:%"load argument at index 2 from buffer"]] = load i8*, i8** [[POINTER_TO_ERASED_TABLE_2]], align 1
76+
// CHECK: [[UNERASED_TABLE_2:%[0-9]+]] = bitcast i8* [[ERASED_TABLE_2]] to i8**
77+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_2:%[0-9]+]] = load i8*, i8** [[UNERASED_TABLE_2]], align 1
78+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR_2:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_2]] to %swift.protocol_conformance_descriptor*
79+
// CHECK: [[EQUAL_DESCRIPTORS_2:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR_2]], %swift.protocol_conformance_descriptor* @"$sSi4main1QAAMc")
80+
// CHECK: [[EQUAL_ARGUMENTS_2:%[0-9]+]] = and i1 [[EQUAL_ARGUMENTS_1]], [[EQUAL_DESCRIPTORS_2]]
81+
// CHECK: [[POINTER_TO_ERASED_TABLE_3:%[0-9]+]] = getelementptr i8*, i8** %1, i64 3
82+
// CHECK: [[ERASED_TABLE_3:%"load argument at index 3 from buffer"]] = load i8*, i8** [[POINTER_TO_ERASED_TABLE_3]], align 1
83+
// CHECK: [[UNERASED_TABLE_3:%[0-9]+]] = bitcast i8* [[ERASED_TABLE_3]] to i8**
84+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_3:%[0-9]+]] = load i8*, i8** [[UNERASED_TABLE_3]], align 1
85+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR_3:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_3]] to %swift.protocol_conformance_descriptor*
86+
// CHECK: [[EQUAL_DESCRIPTORS_3:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR_3]], %swift.protocol_conformance_descriptor* @"$sSi4main1RAAMc")
87+
// CHECK: [[EQUAL_ARGUMENTS_3:%[0-9]+]] = and i1 [[EQUAL_ARGUMENTS_2]], [[EQUAL_DESCRIPTORS_3]]
88+
// CHECK: br i1 [[EQUAL_ARGUMENTS_3]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
6889
// CHECK: [[EXIT_PRESPECIALIZED]]:
6990
// CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i8**, i8**, i8**, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 }
7091
// CHECK: [[EXIT_NORMAL]]:

test/IRGen/prespecialized-metadata/struct-inmodule-1argument-4conformance-1distinct_use.swift

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,35 @@ doit()
6868
// CHECK: %"load argument at index 0 from buffer" = load i8*, i8** [[ERASED_TYPE_ADDRESS]]
6969
// CHECK: [[EQUAL_TYPE:%[0-9]+]] = icmp eq i8* bitcast (%swift.type* @"$sSiN" to i8*), %"load argument at index 0 from buffer"
7070
// CHECK: [[EQUAL_TYPES:%[0-9]+]] = and i1 true, [[EQUAL_TYPE]]
71-
// CHECK: br i1 [[EQUAL_TYPES]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
71+
// CHECK: [[POINTER_TO_ERASED_TABLE_1:%[0-9]+]] = getelementptr i8*, i8** %1, i64 1
72+
// CHECK: [[ERASED_TABLE_1:%"load argument at index 1 from buffer"]] = load i8*, i8** [[POINTER_TO_ERASED_TABLE_1]], align 1
73+
// CHECK: [[UNERASED_TABLE_1:%[0-9]+]] = bitcast i8* [[ERASED_TABLE_1]] to i8**
74+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_1:%[0-9]+]] = load i8*, i8** [[UNERASED_TABLE_1]], align 1
75+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR_1:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_1]] to %swift.protocol_conformance_descriptor*
76+
// CHECK: [[EQUAL_DESCRIPTORS_1:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR_1]], %swift.protocol_conformance_descriptor* @"$sSi4main1PAAMc")
77+
// CHECK: [[EQUAL_ARGUMENTS_1:%[0-9]+]] = and i1 [[EQUAL_TYPES]], [[EQUAL_DESCRIPTORS_1]]
78+
// CHECK: [[POINTER_TO_ERASED_TABLE_2:%[0-9]+]] = getelementptr i8*, i8** %1, i64 2
79+
// CHECK: [[ERASED_TABLE_2:%"load argument at index 2 from buffer"]] = load i8*, i8** [[POINTER_TO_ERASED_TABLE_2]], align 1
80+
// CHECK: [[UNERASED_TABLE_2:%[0-9]+]] = bitcast i8* [[ERASED_TABLE_2]] to i8**
81+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_2:%[0-9]+]] = load i8*, i8** [[UNERASED_TABLE_2]], align 1
82+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR_2:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_2]] to %swift.protocol_conformance_descriptor*
83+
// CHECK: [[EQUAL_DESCRIPTORS_2:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR_2]], %swift.protocol_conformance_descriptor* @"$sSi4main1QAAMc")
84+
// CHECK: [[EQUAL_ARGUMENTS_2:%[0-9]+]] = and i1 [[EQUAL_ARGUMENTS_1]], [[EQUAL_DESCRIPTORS_2]]
85+
// CHECK: [[POINTER_TO_ERASED_TABLE_3:%[0-9]+]] = getelementptr i8*, i8** %1, i64 3
86+
// CHECK: [[ERASED_TABLE_3:%"load argument at index 3 from buffer"]] = load i8*, i8** [[POINTER_TO_ERASED_TABLE_3]], align 1
87+
// CHECK: [[UNERASED_TABLE_3:%[0-9]+]] = bitcast i8* [[ERASED_TABLE_3]] to i8**
88+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_3:%[0-9]+]] = load i8*, i8** [[UNERASED_TABLE_3]], align 1
89+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR_3:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_3]] to %swift.protocol_conformance_descriptor*
90+
// CHECK: [[EQUAL_DESCRIPTORS_3:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR_3]], %swift.protocol_conformance_descriptor* @"$sSi4main1RAAMc")
91+
// CHECK: [[EQUAL_ARGUMENTS_3:%[0-9]+]] = and i1 [[EQUAL_ARGUMENTS_2]], [[EQUAL_DESCRIPTORS_3]]
92+
// CHECK: [[POINTER_TO_ERASED_TABLE_4:%[0-9]+]] = getelementptr i8*, i8** %1, i64 4
93+
// CHECK: [[ERASED_TABLE_4:%"load argument at index 4 from buffer"]] = load i8*, i8** [[POINTER_TO_ERASED_TABLE_4]], align 1
94+
// CHECK: [[UNERASED_TABLE_4:%[0-9]+]] = bitcast i8* [[ERASED_TABLE_4]] to i8**
95+
// CHECK: [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_4:%[0-9]+]] = load i8*, i8** [[UNERASED_TABLE_4]], align 1
96+
// CHECK: [[PROVIDED_PROTOCOL_DESCRIPTOR_4:%[0-9]+]] = bitcast i8* [[UNCAST_PROVIDED_PROTOCOL_DESCRIPTOR_4]] to %swift.protocol_conformance_descriptor*
97+
// CHECK: [[EQUAL_DESCRIPTORS_4:%[0-9]+]] = call swiftcc i1 @swift_compareProtocolConformanceDescriptors(%swift.protocol_conformance_descriptor* [[PROVIDED_PROTOCOL_DESCRIPTOR_4]], %swift.protocol_conformance_descriptor* @"$sSi4main1SAAMc")
98+
// CHECK: [[EQUAL_ARGUMENTS_4:%[0-9]+]] = and i1 [[EQUAL_ARGUMENTS_3]], [[EQUAL_DESCRIPTORS_4]]
99+
// CHECK: br i1 [[EQUAL_ARGUMENTS_4]], label %[[EXIT_PRESPECIALIZED:[0-9]+]], label %[[EXIT_NORMAL:[0-9]+]]
72100
// CHECK: [[EXIT_PRESPECIALIZED]]:
73101
// CHECK: ret %swift.metadata_response { %swift.type* getelementptr inbounds (%swift.full_type, %swift.full_type* bitcast (<{ i8**, [[INT]], %swift.type_descriptor*, %swift.type*, i8**, i8**, i8**, i8**, i32{{(, \[4 x i8\])?}}, i64 }>* @"$s4main5ValueVySiGMf" to %swift.full_type*), i32 0, i32 1), [[INT]] 0 }
74102
// CHECK: [[EXIT_NORMAL]]:

0 commit comments

Comments
 (0)