Skip to content

Commit cecd6af

Browse files
authored
Merge pull request #3785 from swiftwasm/main
2 parents 68374a1 + 5bc4642 commit cecd6af

15 files changed

+235
-89
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 77 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -547,9 +547,8 @@ static void collectGlobalList(IRGenModule &IGM,
547547
static llvm::GlobalVariable *
548548
emitGlobalList(IRGenModule &IGM, ArrayRef<llvm::WeakTrackingVH> handles,
549549
StringRef name, StringRef section,
550-
llvm::GlobalValue::LinkageTypes linkage,
551-
llvm::Type *eltTy,
552-
bool isConstant) {
550+
llvm::GlobalValue::LinkageTypes linkage, llvm::Type *eltTy,
551+
bool isConstant, bool asContiguousArray) {
553552
// Do nothing if the list is empty.
554553
if (handles.empty()) return nullptr;
555554

@@ -558,6 +557,31 @@ emitGlobalList(IRGenModule &IGM, ArrayRef<llvm::WeakTrackingVH> handles,
558557
// so that the linker doesn't accidentally put padding in the list.
559558
Alignment alignment = IGM.getPointerAlignment();
560559

560+
if (!asContiguousArray) {
561+
// Emit as individual globals, which is required for conditional runtime
562+
// records to work.
563+
for (auto &handle : handles) {
564+
llvm::Constant *elt = cast<llvm::Constant>(&*handle);
565+
std::string eltName = name.str() + "_" + elt->getName().str();
566+
if (elt->getType() != eltTy)
567+
elt = llvm::ConstantExpr::getBitCast(elt, eltTy);
568+
auto var = new llvm::GlobalVariable(IGM.Module, eltTy, isConstant,
569+
linkage, elt, eltName);
570+
var->setSection(section);
571+
var->setAlignment(llvm::MaybeAlign(alignment.getValue()));
572+
disableAddressSanitizer(IGM, var);
573+
if (llvm::GlobalValue::isLocalLinkage(linkage))
574+
IGM.addUsedGlobal(var);
575+
576+
if (IGM.IRGen.Opts.ConditionalRuntimeRecords) {
577+
// Allow dead-stripping `var` (the runtime record from the global list)
578+
// when `handle` / `elt` (the underlaying entity) is not referenced.
579+
IGM.appendLLVMUsedConditionalEntry(var, elt->stripPointerCasts());
580+
}
581+
}
582+
return nullptr;
583+
}
584+
561585
// We have an array of value handles, but we need an array of constants.
562586
SmallVector<llvm::Constant*, 8> elts;
563587
elts.reserve(handles.size());
@@ -1037,36 +1061,41 @@ void IRGenModule::emitGlobalLists() {
10371061
if (ObjCInterop) {
10381062
// Objective-C class references go in a variable with a meaningless
10391063
// name but a magic section.
1040-
emitGlobalList(*this, ObjCClasses, "objc_classes",
1041-
GetObjCSectionName("__objc_classlist",
1042-
"regular,no_dead_strip"),
1043-
llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
1064+
emitGlobalList(
1065+
*this, ObjCClasses, "objc_classes",
1066+
GetObjCSectionName("__objc_classlist", "regular,no_dead_strip"),
1067+
llvm::GlobalValue::InternalLinkage, Int8PtrTy, /*isConstant*/ false,
1068+
/*asContiguousArray*/ false);
10441069

10451070
// So do resilient class stubs.
1046-
emitGlobalList(*this, ObjCClassStubs, "objc_class_stubs",
1047-
GetObjCSectionName("__objc_stublist",
1048-
"regular,no_dead_strip"),
1049-
llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
1071+
emitGlobalList(
1072+
*this, ObjCClassStubs, "objc_class_stubs",
1073+
GetObjCSectionName("__objc_stublist", "regular,no_dead_strip"),
1074+
llvm::GlobalValue::InternalLinkage, Int8PtrTy, /*isConstant*/ false,
1075+
/*asContiguousArray*/ true);
10501076

10511077
// So do categories.
1052-
emitGlobalList(*this, ObjCCategories, "objc_categories",
1053-
GetObjCSectionName("__objc_catlist",
1054-
"regular,no_dead_strip"),
1055-
llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
1078+
emitGlobalList(
1079+
*this, ObjCCategories, "objc_categories",
1080+
GetObjCSectionName("__objc_catlist", "regular,no_dead_strip"),
1081+
llvm::GlobalValue::InternalLinkage, Int8PtrTy, /*isConstant*/ false,
1082+
/*asContiguousArray*/ true);
10561083

10571084
// And categories on class stubs.
1058-
emitGlobalList(*this, ObjCCategoriesOnStubs, "objc_categories_stubs",
1059-
GetObjCSectionName("__objc_catlist2",
1060-
"regular,no_dead_strip"),
1061-
llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
1062-
1063-
// Emit nonlazily realized class references in a second magic section to make
1064-
// sure they are realized by the Objective-C runtime before any instances
1065-
// are allocated.
1066-
emitGlobalList(*this, ObjCNonLazyClasses, "objc_non_lazy_classes",
1067-
GetObjCSectionName("__objc_nlclslist",
1068-
"regular,no_dead_strip"),
1069-
llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
1085+
emitGlobalList(
1086+
*this, ObjCCategoriesOnStubs, "objc_categories_stubs",
1087+
GetObjCSectionName("__objc_catlist2", "regular,no_dead_strip"),
1088+
llvm::GlobalValue::InternalLinkage, Int8PtrTy, /*isConstant*/ false,
1089+
/*asContiguousArray*/ true);
1090+
1091+
// Emit nonlazily realized class references in a second magic section to
1092+
// make sure they are realized by the Objective-C runtime before any
1093+
// instances are allocated.
1094+
emitGlobalList(
1095+
*this, ObjCNonLazyClasses, "objc_non_lazy_classes",
1096+
GetObjCSectionName("__objc_nlclslist", "regular,no_dead_strip"),
1097+
llvm::GlobalValue::InternalLinkage, Int8PtrTy, /*isConstant*/ false,
1098+
/*asContiguousArray*/ true);
10701099
}
10711100

10721101
// @llvm.used
@@ -1076,15 +1105,15 @@ void IRGenModule::emitGlobalLists() {
10761105
emitGlobalList(*this, LLVMUsed, "llvm.used", "llvm.metadata",
10771106
llvm::GlobalValue::AppendingLinkage,
10781107
Int8PtrTy,
1079-
false);
1108+
/*isConstant*/false, /*asContiguousArray*/true);
10801109

10811110
// Collect llvm.compiler.used globals already in the module (coming
10821111
// from ClangCodeGen).
10831112
collectGlobalList(*this, LLVMCompilerUsed, "llvm.compiler.used");
10841113
emitGlobalList(*this, LLVMCompilerUsed, "llvm.compiler.used", "llvm.metadata",
10851114
llvm::GlobalValue::AppendingLinkage,
10861115
Int8PtrTy,
1087-
false);
1116+
/*isConstant*/false, /*asContiguousArray*/true);
10881117
}
10891118

10901119
static bool hasCodeCoverageInstrumentation(SILFunction &f, SILModule &m) {
@@ -3720,39 +3749,34 @@ IRGenModule::emitDirectRelativeReference(llvm::Constant *target,
37203749

37213750
/// Expresses that `var` is removable (dead-strippable) when `dependsOn` is not
37223751
/// referenced.
3723-
static void appendLLVMUsedConditionalEntry(IRGenModule &IGM,
3724-
llvm::GlobalVariable *var,
3725-
llvm::Constant *dependsOn) {
3752+
void IRGenModule::appendLLVMUsedConditionalEntry(llvm::GlobalVariable *var,
3753+
llvm::Constant *dependsOn) {
37263754
llvm::Metadata *metadata[] = {
37273755
// (1) which variable is being conditionalized, "target"
37283756
llvm::ConstantAsMetadata::get(var),
37293757
// (2) type, not relevant for a single-edge condition
37303758
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
3731-
llvm::Type::getInt32Ty(IGM.Module.getContext()), 0)),
3759+
llvm::Type::getInt32Ty(Module.getContext()), 0)),
37323760
// (3) the "edge" that holds the target alive, if it's missing the target
37333761
// is allowed to be removed
3734-
llvm::MDNode::get(IGM.Module.getContext(),
3762+
llvm::MDNode::get(Module.getContext(),
37353763
{
37363764
llvm::ConstantAsMetadata::get(dependsOn),
37373765
}),
37383766
};
37393767
auto *usedConditional =
3740-
IGM.Module.getOrInsertNamedMetadata("llvm.used.conditional");
3741-
usedConditional->addOperand(
3742-
llvm::MDNode::get(IGM.Module.getContext(), metadata));
3768+
Module.getOrInsertNamedMetadata("llvm.used.conditional");
3769+
usedConditional->addOperand(llvm::MDNode::get(Module.getContext(), metadata));
37433770
}
37443771

37453772
/// Expresses that `var` is removable (dead-strippable) when either the protocol
37463773
/// from `record` is not referenced or the type from `record` is not referenced.
3747-
static void
3748-
appendLLVMUsedConditionalEntry(IRGenModule &IGM, llvm::GlobalVariable *var,
3749-
const ConformanceDescription &record) {
3750-
auto *protocol =
3751-
IGM.getAddrOfProtocolDescriptor(record.conformance->getProtocol())
3752-
->stripPointerCasts();
3753-
auto *type = IGM.getAddrOfTypeContextDescriptor(
3754-
record.conformance->getType()->getAnyNominal(),
3755-
DontRequireMetadata)
3774+
void IRGenModule::appendLLVMUsedConditionalEntry(
3775+
llvm::GlobalVariable *var, const ProtocolConformance *conformance) {
3776+
auto *protocol = getAddrOfProtocolDescriptor(conformance->getProtocol())
3777+
->stripPointerCasts();
3778+
auto *type = getAddrOfTypeContextDescriptor(
3779+
conformance->getType()->getAnyNominal(), DontRequireMetadata)
37563780
->stripPointerCasts();
37573781

37583782
llvm::Metadata *metadata[] = {
@@ -3761,18 +3785,17 @@ appendLLVMUsedConditionalEntry(IRGenModule &IGM, llvm::GlobalVariable *var,
37613785
// (2) type, "1" = if either edge is missing, the target is allowed to be
37623786
// removed.
37633787
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
3764-
llvm::Type::getInt32Ty(IGM.Module.getContext()), 1)),
3788+
llvm::Type::getInt32Ty(Module.getContext()), 1)),
37653789
// (3) list of edges
3766-
llvm::MDNode::get(IGM.Module.getContext(),
3790+
llvm::MDNode::get(Module.getContext(),
37673791
{
37683792
llvm::ConstantAsMetadata::get(protocol),
37693793
llvm::ConstantAsMetadata::get(type),
37703794
}),
37713795
};
37723796
auto *usedConditional =
3773-
IGM.Module.getOrInsertNamedMetadata("llvm.used.conditional");
3774-
usedConditional->addOperand(
3775-
llvm::MDNode::get(IGM.Module.getContext(), metadata));
3797+
Module.getOrInsertNamedMetadata("llvm.used.conditional");
3798+
usedConditional->addOperand(llvm::MDNode::get(Module.getContext(), metadata));
37763799
}
37773800

37783801
/// Emit the protocol descriptors list and return it (if asContiguousArray is
@@ -3854,7 +3877,7 @@ llvm::Constant *IRGenModule::emitSwiftProtocols(bool asContiguousArray) {
38543877
if (IRGen.Opts.ConditionalRuntimeRecords) {
38553878
// Allow dead-stripping `var` (the protocol record) when the protocol
38563879
// (descriptorRef) is not referenced.
3857-
appendLLVMUsedConditionalEntry(*this, var, descriptorRef.getValue());
3880+
appendLLVMUsedConditionalEntry(var, descriptorRef.getValue());
38583881
}
38593882
}
38603883

@@ -3948,7 +3971,7 @@ llvm::Constant *IRGenModule::emitProtocolConformances(bool asContiguousArray) {
39483971
if (IRGen.Opts.ConditionalRuntimeRecords) {
39493972
// Allow dead-stripping `var` (the conformance record) when the protocol
39503973
// or type (from the conformance) is not referenced.
3951-
appendLLVMUsedConditionalEntry(*this, var, record);
3974+
appendLLVMUsedConditionalEntry(var, record.conformance);
39523975
}
39533976
}
39543977

@@ -4063,7 +4086,7 @@ llvm::Constant *IRGenModule::emitTypeMetadataRecords(bool asContiguousArray) {
40634086
if (IRGen.Opts.ConditionalRuntimeRecords) {
40644087
// Allow dead-stripping `var` (the type record) when the type (`ref`) is
40654088
// not referenced.
4066-
appendLLVMUsedConditionalEntry(*this, var, ref.getValue());
4089+
appendLLVMUsedConditionalEntry(var, ref.getValue());
40674090
}
40684091
}
40694092

lib/IRGen/GenReflection.cpp

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -676,11 +676,20 @@ class AssociatedTypeMetadataBuilder : public ReflectionMetadataBuilder {
676676

677677
llvm::GlobalVariable *emit() {
678678
auto section = IGM.getAssociatedTypeMetadataSectionName();
679-
return ReflectionMetadataBuilder::emit(
680-
[&](IRGenModule &IGM, ConstantInit init) -> llvm::Constant* {
681-
return IGM.getAddrOfReflectionAssociatedTypeDescriptor(Conformance,init);
682-
},
683-
section);
679+
llvm::GlobalVariable *var = ReflectionMetadataBuilder::emit(
680+
[&](IRGenModule &IGM, ConstantInit init) -> llvm::Constant * {
681+
return IGM.getAddrOfReflectionAssociatedTypeDescriptor(Conformance,
682+
init);
683+
},
684+
section);
685+
686+
if (IGM.IRGen.Opts.ConditionalRuntimeRecords) {
687+
// Allow dead-stripping `var` (the reflection record) when the protocol
688+
// or type (from the conformance) is not referenced.
689+
IGM.appendLLVMUsedConditionalEntry(var, Conformance);
690+
}
691+
692+
return var;
684693
}
685694
};
686695

@@ -856,12 +865,21 @@ class FieldTypeMetadataBuilder : public ReflectionMetadataBuilder {
856865

857866
llvm::GlobalVariable *emit() {
858867
auto section = IGM.getFieldTypeMetadataSectionName();
859-
return ReflectionMetadataBuilder::emit(
860-
[&](IRGenModule &IGM, ConstantInit definition) -> llvm::Constant* {
861-
return IGM.getAddrOfReflectionFieldDescriptor(
862-
NTD->getDeclaredType()->getCanonicalType(), definition);
863-
},
864-
section);
868+
llvm::GlobalVariable *var = ReflectionMetadataBuilder::emit(
869+
[&](IRGenModule &IGM, ConstantInit definition) -> llvm::Constant * {
870+
return IGM.getAddrOfReflectionFieldDescriptor(
871+
NTD->getDeclaredType()->getCanonicalType(), definition);
872+
},
873+
section);
874+
875+
if (IGM.IRGen.Opts.ConditionalRuntimeRecords) {
876+
// Allow dead-stripping `var` (the reflection record) when the type
877+
// (NTD) is not referenced.
878+
auto ref = IGM.getTypeEntityReference(const_cast<NominalTypeDecl *>(NTD));
879+
IGM.appendLLVMUsedConditionalEntry(var, ref.getValue());
880+
}
881+
882+
return var;
865883
}
866884
};
867885

lib/IRGen/IRGenModule.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,11 @@ private: \
14621462

14631463
TypeEntityReference getTypeEntityReference(GenericTypeDecl *D);
14641464

1465+
void appendLLVMUsedConditionalEntry(llvm::GlobalVariable *var,
1466+
llvm::Constant *dependsOn);
1467+
void appendLLVMUsedConditionalEntry(llvm::GlobalVariable *var,
1468+
const ProtocolConformance *conformance);
1469+
14651470
llvm::Constant *
14661471
getAddrOfTypeMetadata(CanType concreteType,
14671472
TypeMetadataCanonicality canonicality =

lib/IRGen/LoadableByAddress.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,8 @@ void LargeValueVisitor::visitTupleInst(SingleValueInstruction *instr) {
984984

985985
void LargeValueVisitor::visitAllocStackInst(AllocStackInst *instr) {
986986
SILType currSILType = instr->getType().getObjectType();
987-
if (getInnerFunctionType(currSILType)) {
987+
if (pass.containsDifferentFunctionSignature(pass.F->getLoweredFunctionType(),
988+
currSILType)) {
988989
pass.allocStackInstsToMod.push_back(instr);
989990
}
990991
}

test/IRGen/MachO-objc-sections.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class D {
2121
// CHECK-MACHO: @"$s4main1CCMf" = {{.*}}, section "__DATA,__objc_data, regular"
2222
// CHECK-MACHO: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section "__DATA,__objc_protolist,coalesced,no_dead_strip"
2323
// CHECK-MACHO: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section "__DATA,__objc_protorefs,coalesced,no_dead_strip"
24-
// CHECK-MACHO: @objc_classes = {{.*}}, section "__DATA,__objc_classlist,regular,no_dead_strip"
24+
// CHECK-MACHO: @"objc_classes_$s4main1CCN" = {{.*}}, section "__DATA,__objc_classlist,regular,no_dead_strip"
25+
// CHECK-MACHO: @"objc_classes_$s4main1DCN" = {{.*}}, section "__DATA,__objc_classlist,regular,no_dead_strip"
2526
// CHECK-MACHO: @objc_categories = {{.*}}, section "__DATA,__objc_catlist,regular,no_dead_strip"
2627
// CHECK-MACHO: @objc_non_lazy_classes = {{.*}}, section "__DATA,__objc_nlclslist,regular,no_dead_strip"
2728

test/IRGen/conditional-dead-strip-exec.swift

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33

44
// RUN: %empty-directory(%t)
55

6-
// RUN: %target-build-swift -Xfrontend -disable-objc-interop \
7-
// RUN: -Xfrontend -disable-reflection-metadata -Xfrontend -disable-reflection-names \
8-
// RUN: -Xfrontend -conditional-runtime-records \
9-
// RUN: %s -emit-ir -o %t/main.ll
6+
// RUN: %target-build-swift -Xfrontend -conditional-runtime-records %s -emit-ir -o %t/main.ll
107

118
// RUN: %target-clang %t/main.ll -isysroot %sdk -L%swift_obj_root/lib/swift/%target-sdk-name -flto -o %t/main
129
// RUN: %target-run %t/main | %FileCheck %s
@@ -48,6 +45,10 @@ class UsedClass : UnusedProto, ActuallyUsedProto {
4845
public func bark() { print("UsedClass.bark") }
4946
}
5047

48+
// (9) unused protocol with associated type
49+
protocol ProtoWithAssocType { associatedtype T }
50+
struct Implementor : ProtoWithAssocType { typealias T = Int }
51+
5152
print("Hello!")
5253
func1_used()
5354
let o = UsedClass()
@@ -71,6 +72,11 @@ p.bark()
7172
// (2)
7273
// NM-NOT: $s4main10func2_deadyyF
7374

75+
// (9)
76+
// NM-NOT: $s4main11ImplementorVAA18ProtoWithAssocTypeAAMA
77+
// NM-NOT: $s4main11ImplementorVMf
78+
// NM-NOT: $s4main11ImplementorVMn
79+
7480
// (4)
7581
// NM-NOT: $s4main11TheProtocolMp
7682

test/IRGen/conditional-dead-strip-ir.swift

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
// enum, protocol, and protocol conformance records as conditionally removable
33
// via !llvm.used.conditional metadata.
44

5-
// RUN: %target-build-swift -Xfrontend -disable-objc-interop -Xfrontend -conditional-runtime-records \
6-
// RUN: %s -emit-ir -o - | %FileCheck %s
5+
// RUN: %target-build-swift -Xfrontend -conditional-runtime-records -Xfrontend -disable-objc-interop %s -emit-ir -o - | %FileCheck %s
76

87
public protocol TheProtocol {
98
}
@@ -25,19 +24,25 @@ public enum Enum {
2524
// CHECK-SAME: @"$s4main4EnumOHn"
2625
// CHECK-SAME: ], section "llvm.metadata"
2726

28-
// CHECK: !llvm.used.conditional = !{[[C1:!.*]], [[C2:!.*]], [[C3:!.*]], [[C4:!.*]], [[C5:!.*]]}
27+
// CHECK: !llvm.used.conditional = !{[[M1:!.*]], [[M2:!.*]], [[M3:!.*]], [[M4:!.*]], [[C1:!.*]], [[C2:!.*]], [[C3:!.*]], [[C4:!.*]], [[C5:!.*]]}
2928

30-
// CHECK: [[C1]] = !{{{.*}} @"$s4main11TheProtocolHr", i32 0, [[C1A:!.*]]}
31-
// CHECK: [[C1A]] = !{{{.*}} @"$s4main11TheProtocolMp"}
29+
// CHECK-DAG: [[M1]] = !{{{.*}} @"$s4main11TheProtocol_pMF", i32 0, [[M1A:!.*]]}
30+
// CHECK-DAG: [[M1A]] = !{{{.*}} @"$s4main11TheProtocolMp"
31+
// CHECK-DAG: [[M2]] = !{{{.*}} @"$s4main5ClassCMF", i32 0, [[M2A:!.*]]}
32+
// CHECK-DAG: [[M2A]] = !{{{.*}} @"$s4main5ClassCMn"
33+
// CHECK-DAG: [[M3]] = !{{{.*}} @"$s4main6StructVMF", i32 0, [[M3A:!.*]]}
34+
// CHECK-DAG: [[M3A]] = !{{{.*}} @"$s4main6StructVMn"
35+
// CHECK-DAG: [[M4]] = !{{{.*}} @"$s4main4EnumOMF", i32 0, [[M4A:!.*]]}
36+
// CHECK-DAG: [[M4A]] = !{{{.*}} @"$s4main4EnumOMn"
3237

33-
// CHECK: [[C2]] = !{{{.*}} @"$s4main5ClassCAA11TheProtocolAAHc", i32 1, [[C2A:!.*]]}
34-
// CHECK: [[C2A]] = !{{{.*}} @"$s4main11TheProtocolMp", {{.*}} @"$s4main5ClassCMn"}
38+
// CHECK-DAG: [[C1]] = !{{{.*}} @"$s4main11TheProtocolHr", i32 0, [[C1A:!.*]]}
39+
// CHECK-DAG: [[C1A]] = !{{{.*}} @"$s4main11TheProtocolMp"}
3540

36-
// CHECK: [[C3]] = !{{{.*}} @"$s4main5ClassCHn", i32 0, [[C3A:!.*]]}
37-
// CHECK: [[C3A]] = !{{{.*}} @"$s4main5ClassCMn"}
41+
// CHECK-DAG: [[C2]] = !{{{.*}} @"$s4main5ClassCAA11TheProtocolAAHc", i32 1, [[C2A:!.*]]}
42+
// CHECK-DAG: [[C2A]] = !{{{.*}} @"$s4main11TheProtocolMp", {{.*}} @"$s4main5ClassCMn"}
3843

39-
// CHECK: [[C4]] = !{{{.*}} @"$s4main6StructVHn", i32 0, [[C4A:!.*]]}
40-
// CHECK: [[C4A]] = !{{{.*}} @"$s4main6StructVMn"}
44+
// CHECK-DAG: [[C3]] = !{{{.*}} @"$s4main5ClassCHn", i32 0, [[M2A:!.*]]}
4145

42-
// CHECK: [[C5]] = !{{{.*}} @"$s4main4EnumOHn", i32 0, [[C5A:!.*]]}
43-
// CHECK: [[C5A]] = !{{{.*}} @"$s4main4EnumOMn"}
46+
// CHECK-DAG: [[C4]] = !{{{.*}} @"$s4main6StructVHn", i32 0, [[M3A:!.*]]}
47+
48+
// CHECK-DAG: [[C5]] = !{{{.*}} @"$s4main4EnumOHn", i32 0, [[M4A:!.*]]}

0 commit comments

Comments
 (0)