Skip to content

Commit eee33a7

Browse files
committed
GlobalOpt: bail is the initializer instructions of a global variable contain "undef"
Fixes a compiler crash rdar://75364429
1 parent 28a5eee commit eee33a7

File tree

3 files changed

+43
-0
lines changed

3 files changed

+43
-0
lines changed

lib/SIL/IR/SILGlobalVariable.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ BuiltinInst *SILGlobalVariable::getOffsetSubtract(const TupleExtractInst *TE,
111111

112112
bool SILGlobalVariable::isValidStaticInitializerInst(const SILInstruction *I,
113113
SILModule &M) {
114+
for (const Operand &op : I->getAllOperands()) {
115+
// Rule out SILUndef and SILArgument.
116+
if (!isa<SingleValueInstruction>(op.get()))
117+
return false;
118+
}
114119
switch (I->getKind()) {
115120
case SILInstructionKind::BuiltinInst: {
116121
auto *bi = cast<BuiltinInst>(I);

test/SILOptimizer/globalopt_let_propagation.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ var VPI = 3.1415
7272
var VI = 100
7373
var VS = "String2"
7474

75+
struct GenericStruct<T> {
76+
var x: T
77+
}
78+
7579
// Define some static let variables inside a struct.
7680
struct B {
7781
static let PI = 3.1415
@@ -109,6 +113,8 @@ struct B {
109113
static let IT1 = ((10, 20), 30, 40)
110114

111115
static let IT2 = (100, 200, 300)
116+
117+
static let emptyStruct = GenericStruct(x: ())
112118
}
113119

114120
// Define some static let variables inside a class.

test/SILOptimizer/globalopt_trivial_nontrivial_ossa.sil

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ public class TClass {
1818
deinit
1919
}
2020

21+
struct GenericStruct<T> {
22+
var x: T
23+
}
24+
2125
let nontrivialglobal: TClass
2226

2327
// CHECK-LABEL: sil_global hidden [let] @$trivialglobal : $TStruct = {
@@ -32,6 +36,9 @@ sil_global private @globalinit_nontrivialglobal_token : $Builtin.Word
3236

3337
sil_global hidden [let] @$nontrivialglobal : $TClass
3438

39+
sil_global hidden [let] @empty_global : $GenericStruct<()>
40+
sil_global private @empty_global_token : $Builtin.Word
41+
3542
sil private [global_init_once_fn] [ossa] @globalinit_trivialglobal_func : $@convention(c) () -> () {
3643
bb0:
3744
alloc_global @$trivialglobal
@@ -126,3 +133,28 @@ bb0:
126133
return %5 : $Int32
127134
}
128135

136+
// Check that we don't crash on an initializer struct with an "undef" operand.
137+
// CHECK-LABEL: sil hidden [global_init_once_fn] [ossa] @globalinit_empty_global :
138+
// CHECK: struct $GenericStruct<()> (undef : $())
139+
// CHECK-LABEL: } // end sil function 'globalinit_empty_global'
140+
sil hidden [global_init_once_fn] [ossa] @globalinit_empty_global : $@convention(c) () -> () {
141+
bb0:
142+
alloc_global @empty_global
143+
%1 = global_addr @empty_global : $*GenericStruct<()>
144+
%2 = struct $GenericStruct<()> (undef : $())
145+
store %2 to [trivial] %1 : $*GenericStruct<()>
146+
%4 = tuple ()
147+
return %4 : $()
148+
}
149+
150+
sil hidden [global_init] [ossa] @empty_global_accessor : $@convention(thin) () -> Builtin.RawPointer {
151+
bb0:
152+
%0 = global_addr @empty_global_token : $*Builtin.Word
153+
%1 = address_to_pointer %0 : $*Builtin.Word to $Builtin.RawPointer
154+
%2 = function_ref @globalinit_empty_global : $@convention(c) () -> ()
155+
%3 = builtin "once"(%1 : $Builtin.RawPointer, %2 : $@convention(c) () -> ()) : $()
156+
%4 = global_addr @empty_global : $*GenericStruct<()>
157+
%5 = address_to_pointer %4 : $*GenericStruct<()> to $Builtin.RawPointer
158+
return %5 : $Builtin.RawPointer
159+
}
160+

0 commit comments

Comments
 (0)