Skip to content

Commit 243141e

Browse files
authored
[IRGen] When emitting llvm.used.conditional list, strip all pointer casts in dependencies (swiftlang#40678)
1 parent 1ad13c0 commit 243141e

File tree

5 files changed

+66
-10
lines changed

5 files changed

+66
-10
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3766,9 +3766,7 @@ void IRGenModule::appendLLVMUsedConditionalEntry(llvm::GlobalVariable *var,
37663766
llvm::ConstantAsMetadata::get(dependsOn),
37673767
}),
37683768
};
3769-
auto *usedConditional =
3770-
Module.getOrInsertNamedMetadata("llvm.used.conditional");
3771-
usedConditional->addOperand(llvm::MDNode::get(Module.getContext(), metadata));
3769+
UsedConditionals.push_back(llvm::MDNode::get(Module.getContext(), metadata));
37723770
}
37733771

37743772
/// Expresses that `var` is removable (dead-strippable) when either the protocol
@@ -3795,9 +3793,32 @@ void IRGenModule::appendLLVMUsedConditionalEntry(
37953793
llvm::ConstantAsMetadata::get(type),
37963794
}),
37973795
};
3796+
UsedConditionals.push_back(llvm::MDNode::get(Module.getContext(), metadata));
3797+
}
3798+
3799+
void IRGenModule::emitUsedConditionals() {
3800+
if (UsedConditionals.empty())
3801+
return;
3802+
37983803
auto *usedConditional =
37993804
Module.getOrInsertNamedMetadata("llvm.used.conditional");
3800-
usedConditional->addOperand(llvm::MDNode::get(Module.getContext(), metadata));
3805+
3806+
for (auto *M : UsedConditionals) {
3807+
// Process the dependencies ("edges") and strip any pointer casts on them.
3808+
// Those might appear when a dependency is originally added against a
3809+
// declaration only, and later the declaration is RAUW'd with a definition
3810+
// causing a bitcast to get added to the metadata entry in the dependency.
3811+
auto *DependenciesMD =
3812+
dyn_cast_or_null<llvm::MDNode>(M->getOperand(2).get());
3813+
for (unsigned int I = 0; I < DependenciesMD->getNumOperands(); I++) {
3814+
auto *Dependency = DependenciesMD->getOperand(I).get();
3815+
auto *C = llvm::mdconst::extract_or_null<llvm::Constant>(Dependency)
3816+
->stripPointerCasts();
3817+
DependenciesMD->replaceOperandWith(I, llvm::ConstantAsMetadata::get(C));
3818+
}
3819+
3820+
usedConditional->addOperand(M);
3821+
}
38013822
}
38023823

38033824
/// Emit the protocol descriptors list and return it (if asContiguousArray is

lib/IRGen/IRGenModule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,6 +1690,7 @@ bool IRGenModule::finalize() {
16901690
emitSwiftAsyncExtendedFrameInfoWeakRef();
16911691
emitAutolinkInfo();
16921692
emitGlobalLists();
1693+
emitUsedConditionals();
16931694
if (DebugInfo)
16941695
DebugInfo->finalize();
16951696
cleanupClangCodeGenMetadata();

lib/IRGen/IRGenModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,6 +1217,9 @@ class IRGenModule {
12171217
void emitLazyObjCProtocolDefinitions();
12181218
void emitLazyObjCProtocolDefinition(ProtocolDecl *proto);
12191219

1220+
llvm::SmallVector<llvm::MDNode *> UsedConditionals;
1221+
void emitUsedConditionals();
1222+
12201223
void emitGlobalLists();
12211224
void emitAutolinkInfo();
12221225
void cleanupClangCodeGenMetadata();

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@ public enum Enum {
2727
// CHECK: !llvm.used.conditional = !{[[M1:!.*]], [[M2:!.*]], [[M3:!.*]], [[M4:!.*]], [[C1:!.*]], [[C2:!.*]], [[C3:!.*]], [[C4:!.*]], [[C5:!.*]]}
2828

2929
// CHECK-DAG: [[M1]] = !{{{.*}} @"$s4main11TheProtocol_pMF", i32 0, [[M1A:!.*]]}
30-
// CHECK-DAG: [[M1A]] = !{{{.*}} @"$s4main11TheProtocolMp"
30+
// CHECK-DAG: [[M1A]] = {{.*}} @"$s4main11TheProtocolMp"
3131
// CHECK-DAG: [[M2]] = !{{{.*}} @"$s4main5ClassCMF", i32 0, [[M2A:!.*]]}
32-
// CHECK-DAG: [[M2A]] = !{{{.*}} @"$s4main5ClassCMn"
32+
// CHECK-DAG: [[M2A]] = {{.*}} @"$s4main5ClassCMn"
3333
// CHECK-DAG: [[M3]] = !{{{.*}} @"$s4main6StructVMF", i32 0, [[M3A:!.*]]}
34-
// CHECK-DAG: [[M3A]] = !{{{.*}} @"$s4main6StructVMn"
34+
// CHECK-DAG: [[M3A]] = {{.*}} @"$s4main6StructVMn"
3535
// CHECK-DAG: [[M4]] = !{{{.*}} @"$s4main4EnumOMF", i32 0, [[M4A:!.*]]}
36-
// CHECK-DAG: [[M4A]] = !{{{.*}} @"$s4main4EnumOMn"
36+
// CHECK-DAG: [[M4A]] = {{.*}} @"$s4main4EnumOMn"
3737

3838
// CHECK-DAG: [[C1]] = !{{{.*}} @"$s4main11TheProtocolHr", i32 0, [[C1A:!.*]]}
39-
// CHECK-DAG: [[C1A]] = !{{{.*}} @"$s4main11TheProtocolMp"}
39+
// CHECK-DAG: [[C1A]] = {{.*}} @"$s4main11TheProtocolMp"}
4040

4141
// CHECK-DAG: [[C2]] = !{{{.*}} @"$s4main5ClassCAA11TheProtocolAAHc", i32 1, [[C2A:!.*]]}
42-
// CHECK-DAG: [[C2A]] = !{{{.*}} @"$s4main11TheProtocolMp", {{.*}} @"$s4main5ClassCMn"}
42+
// CHECK-DAG: [[C2A]] = {{.*}} @"$s4main11TheProtocolMp", {{.*}} @"$s4main5ClassCMn"}
4343

4444
// CHECK-DAG: [[C3]] = !{{{.*}} @"$s4main5ClassCHn", i32 0, [[M2A:!.*]]}
4545

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-build-swift -Xfrontend -conditional-runtime-records %s -emit-ir -o %t/main.ll
3+
// RUN: %target-clang %t/main.ll -isysroot %sdk -L%swift_obj_root/lib/swift/%target-sdk-name -flto -o %t/main
4+
// RUN: %target-swift-reflection-dump -binary-filename %t/main | %FileCheck %s
5+
6+
// FIXME(mracek): More work needed to get this to work on non-Apple platforms.
7+
// REQUIRES: VENDOR=apple
8+
9+
// For LTO, the linker dlopen()'s the libLTO library, which is a scenario that
10+
// ASan cannot work in ("Interceptors are not working, AddressSanitizer is
11+
// loaded too late").
12+
// REQUIRES: no_asan
13+
14+
public protocol TheProtocol {
15+
}
16+
17+
public class Class: TheProtocol {
18+
}
19+
20+
public struct Struct {
21+
}
22+
23+
public enum Enum {
24+
}
25+
26+
// CHECK: FIELDS:
27+
// CHECK: =======
28+
// CHECK: main.TheProtocol
29+
// CHECK: main.Class
30+
// CHECK: main.Struct
31+
// CHECK: main.Enum

0 commit comments

Comments
 (0)