Skip to content

Commit c6803d6

Browse files
committed
[DebugInfo] Emit debug info for witness tables
This change emits debug info for witness tables passed into generic functions when a generic type is constrained to a protocol. This information is required for LLDB's generic expression evaluator to work in such functions. rdar://104446865
1 parent ecc9093 commit c6803d6

14 files changed

+191
-101
lines changed

include/swift/AST/Types.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7226,7 +7226,10 @@ class GenericTypeParamType : public SubstitutableType,
72267226

72277227
/// Get the name of the generic type parameter.
72287228
Identifier getName() const;
7229-
7229+
7230+
/// Get the canonical <tau>_n_n name;
7231+
Identifier getCanonicalName() const;
7232+
72307233
/// The depth of this generic type parameter, i.e., the number of outer
72317234
/// levels of generic parameter lists that enclose this type parameter.
72327235
///

lib/AST/Type.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2112,8 +2112,10 @@ Identifier GenericTypeParamType::getName() const {
21122112
if (!isCanonical())
21132113
return Name;
21142114

2115-
// Otherwise, we're canonical. Produce an anonymous '<tau>_n_n' name.
2115+
return getCanonicalName();
2116+
}
21162117

2118+
Identifier GenericTypeParamType::getCanonicalName() const {
21172119
// getASTContext() doesn't actually mutate an already-canonical type.
21182120
auto &C = const_cast<GenericTypeParamType*>(this)->getASTContext();
21192121
auto &names = C.CanonicalGenericTypeParamTypeNames;

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,16 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
279279
DebugTypeInfo DebugType,
280280
bool IsLocalToUnit,
281281
std::optional<SILLocation> Loc);
282+
283+
void emitArtificialVariable(IRGenFunction &IGF, llvm::Value *Metadata,
284+
StringRef Name, StringRef Identifier);
285+
282286
void emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
283-
unsigned Depth, unsigned Index, StringRef Name);
287+
GenericTypeParamType *Type);
288+
289+
void emitWitnessTable(IRGenFunction &IGF, llvm::Value *Metadata,
290+
StringRef Name, ProtocolDecl *protocol);
291+
284292
void emitPackCountParameter(IRGenFunction &IGF, llvm::Value *Metadata,
285293
SILDebugVariable VarInfo);
286294

@@ -3899,9 +3907,10 @@ void IRGenDebugInfoImpl::emitGlobalVariableDeclaration(
38993907
Var->addDebugInfo(GV);
39003908
}
39013909

3902-
void IRGenDebugInfoImpl::emitTypeMetadata(IRGenFunction &IGF,
3903-
llvm::Value *Metadata, unsigned Depth,
3904-
unsigned Index, StringRef Name) {
3910+
void IRGenDebugInfoImpl::emitArtificialVariable(IRGenFunction &IGF,
3911+
llvm::Value *Metadata,
3912+
StringRef Name,
3913+
StringRef Identifier) {
39053914
if (Opts.DebugInfoLevel <= IRGenDebugInfoLevel::LineTables)
39063915
return;
39073916

@@ -3910,23 +3919,44 @@ void IRGenDebugInfoImpl::emitTypeMetadata(IRGenFunction &IGF,
39103919
if (!DS || DS->getInlinedFunction()->isTransparent())
39113920
return;
39123921

3913-
llvm::SmallString<8> Buf;
3914-
static const char *Tau = SWIFT_UTF8("\u03C4");
3915-
llvm::raw_svector_ostream OS(Buf);
3916-
OS << '$' << Tau << '_' << Depth << '_' << Index;
3917-
uint64_t PtrWidthInBits = CI.getTargetInfo().getPointerWidth(clang::LangAS::Default);
3922+
uint64_t PtrWidthInBits =
3923+
CI.getTargetInfo().getPointerWidth(clang::LangAS::Default);
39183924
assert(PtrWidthInBits % 8 == 0);
39193925
auto DbgTy = DebugTypeInfo::getTypeMetadata(
39203926
getMetadataType(Name)->getDeclaredInterfaceType().getPointer(),
39213927
Size(PtrWidthInBits / 8),
39223928
Alignment(CI.getTargetInfo().getPointerAlign(clang::LangAS::Default)));
3923-
emitVariableDeclaration(IGF.Builder, Metadata, DbgTy, IGF.getDebugScope(),
3924-
{}, {OS.str().str(), 0, false},
3925-
// swift.type is already a pointer type,
3926-
// having a shadow copy doesn't add another
3927-
// layer of indirection.
3928-
IGF.isAsync() ? CoroDirectValue : DirectValue,
3929-
ArtificialValue);
3929+
emitVariableDeclaration(
3930+
IGF.Builder, Metadata, DbgTy, IGF.getDebugScope(), {},
3931+
{Identifier, 0, false}, // swift.type is already a pointer type,
3932+
// having a shadow copy doesn't add another
3933+
// layer of indirection.
3934+
IGF.isAsync() ? CoroDirectValue : DirectValue, ArtificialValue);
3935+
}
3936+
3937+
void IRGenDebugInfoImpl::emitTypeMetadata(IRGenFunction &IGF,
3938+
llvm::Value *Metadata,
3939+
GenericTypeParamType *Type) {
3940+
auto Name = Type->getName().str();
3941+
llvm::SmallString<8> Buf;
3942+
llvm::raw_svector_ostream OS(Buf);
3943+
OS << "$" << Type->getCanonicalName().str();
3944+
3945+
emitArtificialVariable(IGF, Metadata, Name, OS.str());
3946+
}
3947+
3948+
void IRGenDebugInfoImpl::emitWitnessTable(IRGenFunction &IGF,
3949+
llvm::Value *Metadata, StringRef Name,
3950+
ProtocolDecl *protocol) {
3951+
llvm::SmallString<32> Buf;
3952+
llvm::raw_svector_ostream OS(Buf);
3953+
DebugTypeInfo DbgTy(protocol->getInterfaceType());
3954+
auto MangledName = getMangledName(DbgTy).Canonical;
3955+
OS << "$WT_" << Name << "_" << MangledName;
3956+
// Make sure this ID lives long enough.
3957+
auto Id = IGF.getSwiftModule()->getASTContext().getIdentifier(OS.str());
3958+
3959+
emitArtificialVariable(IGF, Metadata, Name, Id.str());
39303960
}
39313961

39323962
void IRGenDebugInfoImpl::emitPackCountParameter(IRGenFunction &IGF,
@@ -4065,10 +4095,15 @@ void IRGenDebugInfo::emitGlobalVariableDeclaration(
40654095
}
40664096

40674097
void IRGenDebugInfo::emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
4068-
unsigned Depth, unsigned Index,
4069-
StringRef Name) {
4098+
GenericTypeParamType *Type) {
40704099
static_cast<IRGenDebugInfoImpl *>(this)->emitTypeMetadata(IGF, Metadata,
4071-
Depth, Index, Name);
4100+
Type);
4101+
}
4102+
4103+
void IRGenDebugInfo::emitWitnessTable(IRGenFunction &IGF, llvm::Value *Metadata,
4104+
StringRef Name, ProtocolDecl *protocol) {
4105+
static_cast<IRGenDebugInfoImpl *>(this)->emitWitnessTable(IGF, Metadata, Name,
4106+
protocol);
40724107
}
40734108

40744109
void IRGenDebugInfo::emitPackCountParameter(IRGenFunction &IGF,

lib/IRGen/IRGenDebugInfo.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,11 @@ class IRGenDebugInfo {
186186

187187
/// Emit debug metadata for type metadata (for generic types). So meta.
188188
void emitTypeMetadata(IRGenFunction &IGF, llvm::Value *Metadata,
189-
unsigned Depth, unsigned Index, StringRef Name);
189+
GenericTypeParamType *Type);
190+
191+
/// Emit debug metadata for a (protocol) witness table.
192+
void emitWitnessTable(IRGenFunction &IGF, llvm::Value *Metadata,
193+
StringRef Name, ProtocolDecl *protocol);
190194

191195
/// Emit debug info for the IR function parameter holding the size of one or
192196
/// more parameter / type packs.

lib/IRGen/LocalTypeData.cpp

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -412,22 +412,36 @@ static void maybeEmitDebugInfoForLocalTypeData(IRGenFunction &IGF,
412412
if (DS && DS->getInlinedFunction() &&
413413
DS->getInlinedFunction()->isTransparent())
414414
return;
415-
416-
// Only for formal type metadata.
417-
if (key.Kind != LocalTypeDataKind::forFormalTypeMetadata())
415+
// For formal type metadata and witness tables.
416+
ProtocolDecl *proto = nullptr;
417+
418+
if (key.Kind.isAbstractProtocolConformance())
419+
proto = key.Kind.getAbstractProtocolConformance();
420+
else if (key.Kind.isConcreteProtocolConformance())
421+
proto = key.Kind.getConcreteProtocolConformance()->getProtocol();
422+
else if (key.Kind != LocalTypeDataKind::forFormalTypeMetadata())
418423
return;
419424

420425
// Only for archetypes, and not for opened/opaque archetypes.
421426
auto type = dyn_cast<ArchetypeType>(key.Type);
422427
if (!type)
423428
return;
424-
if (!type->isRoot())
429+
if (!type->isRoot() && !proto)
425430
return;
426431
if (!isa<PrimaryArchetypeType>(type) && !isa<PackArchetypeType>(type))
427432
return;
428433

429-
auto *typeParam = type->getInterfaceType()->castTo<GenericTypeParamType>();
430-
auto name = typeParam->getName().str();
434+
auto interfaceType = type->getInterfaceType();
435+
llvm::SmallString<16> name;
436+
if (auto DMT =
437+
llvm::dyn_cast<DependentMemberType>(interfaceType.getPointer())) {
438+
name = DMT->getString();
439+
} else if (auto GTPT = llvm::dyn_cast<GenericTypeParamType>(
440+
interfaceType.getPointer())) {
441+
name = GTPT->getString();
442+
} else {
443+
return;
444+
}
431445

432446
llvm::Value *data = value.getMetadata();
433447

@@ -447,10 +461,12 @@ static void maybeEmitDebugInfoForLocalTypeData(IRGenFunction &IGF,
447461
if (!IGF.IGM.DebugInfo)
448462
return;
449463

450-
IGF.IGM.DebugInfo->emitTypeMetadata(IGF, data,
451-
typeParam->getDepth(),
452-
typeParam->getIndex(),
453-
name);
464+
if (proto) {
465+
IGF.IGM.DebugInfo->emitWitnessTable(IGF, data, name, proto);
466+
} else {
467+
auto *typeParam = type->getInterfaceType()->castTo<GenericTypeParamType>();
468+
IGF.IGM.DebugInfo->emitTypeMetadata(IGF, data, typeParam);
469+
}
454470
}
455471

456472
void

test/DebugInfo/move_function_dbginfo.swift

Lines changed: 6 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -237,19 +237,19 @@ public func copyableVarArgTest(_ k: inout Klass) {
237237
// DWARF-NEXT: DW_AT_artificial (true)
238238
//
239239
// DWARF: DW_TAG_variable
240+
// DWARF: DW_AT_location
241+
// DWARF: DW_AT_name ("$WT_T_$s3out1P_pmD")
242+
// DWARF: DW_AT_type (
243+
// DWARF: DW_AT_artificial (true)
244+
//
245+
// DWARF: DW_TAG_variable
240246
// DWARF-NEXT: DW_AT_location (0x{{[a-z0-9]+}}:
241247
// DWARF-NEXT: [0x{{[a-z0-9]+}}, 0x{{[a-z0-9]+}}):
242248
// DWARF-NEXT: DW_AT_name ("k")
243249
// DWARF-NEXT: DW_AT_decl_file (
244250
// DWARF-NEXT: DW_AT_decl_line (
245251
// DWARF-NEXT: DW_AT_type (
246252
//
247-
// DWARF: DW_TAG_variable
248-
// DWARF-NEXT: DW_AT_location (
249-
// DWARF-NEXT: DW_AT_name ("m")
250-
// DWARF-NEXT: DW_AT_decl_file (
251-
// DWARF-NEXT: DW_AT_decl_line (
252-
// DWARF-NEXT: DW_AT_type (
253253
public func addressOnlyValueTest<T : P>(_ x: T) {
254254
let k = x
255255
k.doSomething()
@@ -265,33 +265,6 @@ public func addressOnlyValueTest<T : P>(_ x: T) {
265265
// CHECK: ret void
266266
// CHECK-NEXT: }
267267
//
268-
// DWARF: DW_AT_linkage_name ("$s3out23addressOnlyValueArgTestyyxnAA1PRzlF")
269-
// DWARF-NEXT: DW_AT_name ("addressOnlyValueArgTest")
270-
// DWARF-NEXT: DW_AT_decl_file (
271-
// DWARF-NEXT: DW_AT_decl_line (
272-
// DWARF-NEXT: DW_AT_type (
273-
// DWARF-NEXT: DW_AT_external (
274-
//
275-
// DWARF: DW_TAG_formal_parameter
276-
// DWARF-NEXT: DW_AT_location (0x{{[a-z0-9]+}}:
277-
// DWARF-NEXT: [0x{{[a-z0-9]+}}, 0x{{[a-z0-9]+}}):
278-
// DWARF-NEXT: DW_AT_name ("k")
279-
// DWARF-NEXT: DW_AT_decl_file (
280-
// DWARF-NEXT: DW_AT_decl_line (
281-
// DWARF-NEXT: DW_AT_type (
282-
//
283-
// DWARF: DW_TAG_variable
284-
// DWARF-NEXT: DW_AT_location (
285-
// DWARF-NEXT: DW_AT_name ("$\317\204_0_0")
286-
// DWARF-NEXT: DW_AT_type (
287-
// DWARF-NEXT: DW_AT_artificial (true)
288-
//
289-
// DWARF: DW_TAG_variable
290-
// DWARF-NEXT: DW_AT_location (
291-
// DWARF-NEXT: DW_AT_name ("m")
292-
// DWARF-NEXT: DW_AT_decl_file (
293-
// DWARF-NEXT: DW_AT_decl_line (
294-
// DWARF-NEXT: DW_AT_type (
295268
public func addressOnlyValueArgTest<T : P>(_ k: __owned T) {
296269
k.doSomething()
297270
let m = consume k
@@ -306,35 +279,6 @@ public func addressOnlyValueArgTest<T : P>(_ k: __owned T) {
306279
// CHECK: ret void
307280
// CHECK-NEXT: }
308281
//
309-
// DWARF: DW_AT_linkage_name ("$s3out18addressOnlyVarTestyyxAA1PRzlF")
310-
// DWARF-NEXT: DW_AT_name ("addressOnlyVarTest")
311-
// DWARF-NEXT: DW_AT_decl_file (
312-
// DWARF-NEXT: DW_AT_decl_line (
313-
// DWARF-NEXT: DW_AT_type (
314-
// DWARF-NEXT: DW_AT_external (
315-
//
316-
// DWARF: DW_TAG_formal_parameter
317-
// DWARF-NEXT: DW_AT_location (
318-
// DWARF-NEXT: DW_AT_name ("x")
319-
// DWARF-NEXT: DW_AT_decl_file (
320-
// DWARF-NEXT: DW_AT_decl_line (
321-
// DWARF-NEXT: DW_AT_type (
322-
//
323-
// DWARF: DW_TAG_variable
324-
// DWARF-NEXT: DW_AT_location (
325-
// DWARF-NEXT: DW_AT_name ("$\317\204_0_0")
326-
// DWARF-NEXT: DW_AT_type (
327-
// DWARF-NEXT: DW_AT_artificial (true)
328-
//
329-
// DWARF: DW_TAG_variable
330-
// DWARF-NEXT: DW_AT_location (0x{{[a-z0-9]+}}:
331-
// DWARF-NEXT: [0x{{[a-z0-9]+}}, 0x{{[a-z0-9]+}}):
332-
// TODO: Missing def in dbg info here.
333-
// DWARF-NEXT: [0x{{[a-z0-9]+}}, 0x{{[a-z0-9]+}}):
334-
// DWARF-NEXT: DW_AT_name ("k")
335-
// DWARF-NEXT: DW_AT_decl_file (
336-
// DWARF-NEXT: DW_AT_decl_line (
337-
// DWARF-NEXT: DW_AT_type (
338282
public func addressOnlyVarTest<T : P>(_ x: T) {
339283
var k = x // << this
340284
k.doSomething()

test/DebugInfo/witness_table.swift

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// RUN: %target-swift-frontend %s -emit-ir -g -o -
2+
import StdlibUnittest
3+
protocol P1 {}
4+
protocol P2 {}
5+
protocol P3 {}
6+
protocol P4 {}
7+
protocol P5 {}
8+
9+
struct I: P1, P2, P4 {}
10+
struct I2: P3 {}
11+
struct I3: P5 {}
12+
13+
struct S<T, U: P3> where T: P1, T: P2 {
14+
let t: T
15+
let u: U
16+
17+
func foo() {
18+
}
19+
//CHECK: ![[foo:[0-9]+]] = distinct !DISubprogram(name: "foo", linkageName: "$s13witness_table1SV3fooyyF",
20+
//CHECK: !DILocalVariable(name: "$WT_T_$s13witness_table2P1_pmD", scope: ![[foo]], {{.*}}, flags: DIFlagArtificial)
21+
//CHECK: !DILocalVariable(name: "$WT_T_$s13witness_table2P2_pmD", scope: ![[foo]], {{.*}}, flags: DIFlagArtificial)
22+
//CHECK: !DILocalVariable(name: "$\CF\84_0_0", scope: ![[foo]], {{.*}}, flags: DIFlagArtificial)
23+
//CHECK: !DILocalVariable(name: "$WT_U_$s13witness_table2P3_pmD", scope: ![[foo]], {{.*}}, flags: DIFlagArtificial)
24+
//CHECK: !DILocalVariable(name: "$\CF\84_0_1", scope: ![[foo]], {{.*}}, flags: DIFlagArtificial)
25+
26+
func bar<V: P4>(v: V) {
27+
}
28+
//CHECK: ![[bar:[0-9]+]] = distinct !DISubprogram(name: "bar", linkageName: "$s13witness_table1SV3bar1vyqd___tAA2P4Rd__lF",
29+
//CHECK: !DILocalVariable(name: "$\CF\84_1_0", scope: ![[bar]], {{.*}}, flags: DIFlagArtificial)
30+
//CHECK: !DILocalVariable(name: "$WT_V_$s13witness_table2P4_pmD", scope: ![[bar]], {{.*}}, flags: DIFlagArtificial)
31+
//CHECK: !DILocalVariable(name: "$WT_T_$s13witness_table2P1_pmD", scope: ![[bar]], {{.*}}, flags: DIFlagArtificial)
32+
//CHECK: !DILocalVariable(name: "$WT_T_$s13witness_table2P2_pmD", scope: ![[bar]], {{.*}}, flags: DIFlagArtificial)
33+
//CHECK: !DILocalVariable(name: "$\CF\84_0_0", scope: ![[bar]], {{.*}}, flags: DIFlagArtificial)
34+
//CHECK: !DILocalVariable(name: "$WT_U_$s13witness_table2P3_pmD", scope: ![[bar]], {{.*}}, flags: DIFlagArtificial)
35+
//CHECK: !DILocalVariable(name: "$\CF\84_0_1", scope: ![[bar]], {{.*}}, flags: DIFlagArtificial)
36+
}
37+
38+
extension S where T: P5 {
39+
func baz() {
40+
}
41+
42+
//CHECK: ![[baz:[0-9]+]] = distinct !DISubprogram(name: "baz", linkageName: "$s13witness_table1SVA2A2P5RzrlE3bazyyF",
43+
//CHECK: !DILocalVariable(name: "$WT_T_$s13witness_table2P5_pmD", scope: ![[baz]], {{.*}}, flags: DIFlagArtificial)
44+
//CHECK: !DILocalVariable(name: "$WT_T_$s13witness_table2P1_pmD", scope: ![[baz]], {{.*}}, flags: DIFlagArtificial)
45+
//CHECK: !DILocalVariable(name: "$WT_T_$s13witness_table2P2_pmD", scope: ![[baz]], {{.*}}, flags: DIFlagArtificial)
46+
//CHECK: !DILocalVariable(name: "$\CF\84_0_0", scope: ![[baz]], {{.*}}, flags: DIFlagArtificial)
47+
//CHECK: !DILocalVariable(name: "$WT_U_$s13witness_table2P3_pmD", scope: ![[baz]], {{.*}}, flags: DIFlagArtificial)
48+
//CHECK: !DILocalVariable(name: "$\CF\84_0_1", scope: ![[baz]], {{.*}}, flags: DIFlagArtificial)
49+
}
50+
51+
S(t: I(), u: I2())
52+
53+
func freeFunc<T1: P1, T2>(t1: T1, t2: T2) where T2: P3, T2: P4 {
54+
}
55+
//CHECK: ![[freeFunc:[0-9]+]] = distinct !DISubprogram(name: "freeFunc", linkageName: "$s13witness_table8freeFunc2t12t2yx_q_tAA2P1RzAA2P3R_AA2P4R_r0_lF",
56+
//CHECK: !DILocalVariable(name: "$\CF\84_0_0", scope: ![[freeFunc]], {{.*}}, flags: DIFlagArtificial)
57+
//CHECK: !DILocalVariable(name: "$\CF\84_0_1", scope: ![[freeFunc]], {{.*}}, flags: DIFlagArtificial)
58+
//CHECK: !DILocalVariable(name: "$WT_T1_$s13witness_table2P1_pmD", scope: ![[freeFunc]], {{.*}}, flags: DIFlagArtificial)
59+
//CHECK: !DILocalVariable(name: "$WT_T2_$s13witness_table2P3_pmD", scope: ![[freeFunc]], {{.*}}, flags: DIFlagArtificial)
60+
//CHECK: !DILocalVariable(name: "$WT_T2_$s13witness_table2P4_pmD", scope: ![[freeFunc]], {{.*}}, flags: DIFlagArtificial)
61+
62+
protocol A {
63+
associatedtype Element
64+
}
65+
66+
func withAssociatedType<T: A>(_: T) where T.Element: A {
67+
}
68+
69+
//CHECK: ![[withAssociatedType:[0-9]+]] = distinct !DISubprogram(name: "withAssociatedType", linkageName: "$s13witness_table18withAssociatedTypeyyxAA1ARzAaC7ElementRpzlF"
70+
//CHECK: !DILocalVariable(name: "$\CF\84_0_0", scope: ![[withAssociatedType]], {{.*}}, flags: DIFlagArtificial)
71+
//CHECK: !DILocalVariable(name: "$WT_T_$s13witness_table1A_pmD", scope: ![[withAssociatedType]], {{.*}}, flags: DIFlagArtificial)
72+
//CHECK: !DILocalVariable(name: "$WT_T.Element_$s13witness_table1A_pmD", scope: ![[withAssociatedType]], {{.*}}, flags: DIFlagArtificial)
73+

test/IRGen/associated_type_witness.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,14 @@ struct Fulfilled<T : P & Q> : Assocked {
7373
// CHECK-LABEL: define internal swiftcc ptr @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5AssocAaEP_AA1PPWT"(ptr %"Fulfilled<T>.Assoc", ptr %"Fulfilled<T>", ptr %"Fulfilled<T>.Assocked")
7474
// CHECK: [[T1:%.*]] = getelementptr inbounds ptr, ptr %"Fulfilled<T>", i64 3
7575
// CHECK-NEXT: [[T2:%.*]] = load ptr, ptr [[T1]], align 8, !invariant.load
76+
// CHECK-NEXT: store ptr %T.P, ptr %T
7677
// CHECK-NEXT: ret ptr [[T2]]
7778

7879
// Associated type witness table access function for Fulfilled.Assoc : Q.
7980
// CHECK-LABEL: define internal swiftcc ptr @"$s23associated_type_witness9FulfilledVyxGAA8AssockedAA5AssocAaEP_AA1QPWT"(ptr %"Fulfilled<T>.Assoc", ptr %"Fulfilled<T>", ptr %"Fulfilled<T>.Assocked")
8081
// CHECK: [[T1:%.*]] = getelementptr inbounds ptr, ptr %"Fulfilled<T>", i64 4
8182
// CHECK-NEXT: [[T2:%.*]] = load ptr, ptr [[T1]], align 8, !invariant.load
83+
// CHECK-NEXT: store ptr %T.Q, ptr %T
8284
// CHECK-NEXT: ret ptr [[T2]]
8385

8486
struct Pair<T, U> : P, Q {}

test/IRGen/conformance_access_path.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ extension Validatable {
1919
public func tested<S: ValidationSuite>(by suite: S.Type) where S.InputType == Self {
2020
// CHECK: [[S_AS_VALIDATION_SUITE_GEP:%[0-9]+]] = getelementptr inbounds ptr, ptr %S.ValidationSuite, i32 1
2121
// CHECK: [[S_AS_VALIDATION_SUITE:%.*]] = load ptr, ptr [[S_AS_VALIDATION_SUITE_GEP]]
22-
// CHECK-NEXT: call swiftcc ptr @swift_getAssociatedConformanceWitness(ptr %S.Validator, ptr %S, ptr %Self,
22+
// CHECK: call swiftcc ptr @swift_getAssociatedConformanceWitness(ptr %S.Validator, ptr %S, ptr %Self,
2323
tested()
2424
}
2525
}

0 commit comments

Comments
 (0)