Skip to content

Commit 0d4980e

Browse files
committed
DeadFunctionElimination: keep global variables alive which are referenced from another global
Fixes a compiler crash in case a private global is only reference from another global variable, for example: ``` private var g1 = 27 let g2 = UnsafePointer(&g1) ``` rdar://117189962
1 parent 7c92a18 commit 0d4980e

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

lib/SILOptimizer/IPO/DeadFunctionElimination.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ class DeadFunctionAndGlobalElimination {
212212
for (const SILInstruction &initInst : *global) {
213213
if (auto *fRef = dyn_cast<FunctionRefInst>(&initInst))
214214
ensureAlive(fRef->getReferencedFunction());
215+
if (auto *gRef = dyn_cast<GlobalAddrInst>(&initInst))
216+
ensureAlive(gRef->getReferencedGlobal());
215217
}
216218
}
217219

test/SILOptimizer/dead_function_elimination.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
// RUN: %target-swift-frontend %s -O -emit-sil | %FileCheck %s
22
// RUN: %target-swift-frontend %s -O -emit-sil -enable-testing | %FileCheck -check-prefix=CHECK-TESTING %s
33

4+
// Check if a private global is kept alive if it's only reference from another global variable.
5+
6+
private var g1 = 27
7+
let g2 = UnsafePointer(&g1)
8+
49
// Check if cycles are removed.
510

611
@inline(never)
@@ -184,6 +189,8 @@ public func keepPtrAlive() {
184189
GFStr.aliveFuncPtr()
185190
}
186191

192+
// CHECK-LABEL: sil_global private @$s25dead_function_elimination2g1{{.*}}
193+
187194
// CHECK-NOT: sil {{.*}}inCycleA
188195
// CHECK-NOT: sil {{.*}}inCycleB
189196
// CHECK-NOT: sil {{.*}}DeadMethod

test/SILOptimizer/remove_unused_func.sil

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,30 @@ sil_global @globalFunctionPointer : $@callee_guaranteed () -> () = {
2525
%initval = thin_to_thick_function %0 : $@convention(thin) () -> () to $@callee_guaranteed () -> ()
2626
}
2727

28+
// CHECK-LABEL: sil_global private @self_referencing_private_global
29+
sil_global private @self_referencing_private_global : $Builtin.RawPointer = {
30+
%0 = global_addr @self_referencing_private_global : $*Builtin.RawPointer
31+
%initval = address_to_pointer %0 : $*Builtin.RawPointer to $Builtin.RawPointer
32+
}
33+
34+
// CHECK-LABEL: sil_global private @referencing_other_private_global
35+
sil_global private @referencing_other_private_global : $Builtin.RawPointer = {
36+
%0 = global_addr @self_referencing_private_global : $*Builtin.RawPointer
37+
%initval = address_to_pointer %0 : $*Builtin.RawPointer to $Builtin.RawPointer
38+
}
39+
40+
// CHECK-LABEL: sil_global @referencing_private_globals
41+
sil_global @referencing_private_globals : $Builtin.RawPointer = {
42+
%0 = global_addr @referencing_other_private_global : $*Builtin.RawPointer
43+
%initval = address_to_pointer %0 : $*Builtin.RawPointer to $Builtin.RawPointer
44+
}
45+
46+
// KEEP-NOT: @dead_self_referencing_private_global
47+
sil_global private @dead_self_referencing_private_global : $Builtin.RawPointer = {
48+
%0 = global_addr @dead_self_referencing_private_global : $*Builtin.RawPointer
49+
%initval = address_to_pointer %0 : $*Builtin.RawPointer to $Builtin.RawPointer
50+
}
51+
2852
// CHECK-LABEL: sil private @alivePrivateFunc
2953
sil private @alivePrivateFunc : $@convention(thin) () -> () {
3054
bb0:

0 commit comments

Comments
 (0)