Skip to content

Commit 0ee51e4

Browse files
committed
StaticInitCloner: skip begin_access instructions when cloning the initial value of a global
Fixes a crash when simplifying a load of an UnsafePointer-global which points to another global. rdar://135223354
1 parent 9d2159c commit 0ee51e4

File tree

4 files changed

+46
-0
lines changed

4 files changed

+46
-0
lines changed

SwiftCompilerSources/Sources/Optimizer/Utilities/StaticInitCloner.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,16 @@ struct StaticInitCloner<Context: MutatingContext> {
4646
return getClonedValue(of: value)
4747
}
4848

49+
if let beginAccess = value as? BeginAccessInst {
50+
// Skip access instructions, which might be generated for UnsafePointer globals which point to other globals.
51+
let clonedOperand = clone(beginAccess.address)
52+
bridged.recordFoldedValue(beginAccess.bridged, clonedOperand.bridged)
53+
return clonedOperand
54+
}
55+
4956
let inst = value.definingInstruction!
57+
assert(!(inst is ScopedInstruction), "global init value must not contain a scoped instruction")
58+
5059
for op in inst.operands {
5160
_ = clone(op.value)
5261
}

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ struct BridgedCloner {
186186
SWIFT_IMPORT_UNSAFE BridgedValue getClonedValue(BridgedValue v);
187187
bool isValueCloned(BridgedValue v) const;
188188
void clone(BridgedInstruction inst);
189+
void recordFoldedValue(BridgedValue origValue, BridgedValue mappedValue);
189190
};
190191

191192
struct BridgedSpecializationCloner {

lib/SILOptimizer/PassManager/PassManager.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,6 +2115,10 @@ void BridgedCloner::clone(BridgedInstruction inst) {
21152115
cloner->cloneInst(inst.unbridged());
21162116
}
21172117

2118+
void BridgedCloner::recordFoldedValue(BridgedValue origValue, BridgedValue mappedValue) {
2119+
cloner->recordFoldedValue(origValue.getSILValue(), mappedValue.getSILValue());
2120+
}
2121+
21182122
static BridgedUtilities::VerifyFunctionFn verifyFunctionFunction;
21192123

21202124
void BridgedUtilities::registerVerifier(VerifyFunctionFn verifyFunctionFn) {

test/SILOptimizer/simplify_load.sil

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ bb0:
6060
return %1 : $Builtin.RawPointer
6161
}
6262

63+
sil_global private @global_char : $Int8
64+
sil_global private [let] @global_pointer : $UnsafeRawPointer
65+
6366
// CHECK-LABEL: sil @load_global_simple
6467
// CHECK-DAG: [[L27:%.*]] = integer_literal $Builtin.Int64, 27
6568
// CHECK-DAG: [[I27:%.*]] = struct $Int64 ([[L27]] : $Builtin.Int64)
@@ -184,6 +187,35 @@ bb0(%0 : $Builtin.RawPointer):
184187
return %4 : $(B, Int64)
185188
}
186189

190+
sil private [global_init_once_fn] @init_global_pointer : $@convention(c) (Builtin.RawPointer) -> () {
191+
bb0(%0 : $Builtin.RawPointer):
192+
alloc_global @global_pointer
193+
%2 = global_addr @global_pointer : $*UnsafeRawPointer
194+
%3 = global_addr @global_char : $*Int8
195+
%4 = begin_access [modify] [dynamic] %3 : $*Int8
196+
%5 = address_to_pointer %4 : $*Int8 to $Builtin.RawPointer
197+
%6 = struct $UnsafeRawPointer (%5 : $Builtin.RawPointer)
198+
end_access %4 : $*Int8
199+
store %6 to %2 : $*UnsafeRawPointer
200+
%9 = tuple ()
201+
return %9 : $()
202+
}
203+
204+
// CHECK-LABEL: sil @load_global_pointer :
205+
// CHECK: %1 = global_addr @global_char
206+
// CHECK-NEXT: %2 = address_to_pointer %1 : $*Int8 to $Builtin.RawPointer
207+
// CHECK-NEXT: %3 = struct $UnsafeRawPointer (%2 : $Builtin.RawPointer)
208+
// CHECK-NEXT: return %3
209+
// CHECK: } // end sil function 'load_global_pointer'
210+
sil @load_global_pointer : $@convention(thin) (Builtin.RawPointer) -> UnsafeRawPointer {
211+
bb0(%0 : $Builtin.RawPointer):
212+
%2 = function_ref @init_global_pointer : $@convention(c) (Builtin.RawPointer) -> ()
213+
%3 = builtin "once"(%0 : $Builtin.RawPointer, %2 : $@convention(c) (Builtin.RawPointer) -> ()) : $Builtin.SILToken
214+
%4 = global_addr @global_pointer : $*UnsafeRawPointer depends_on %3
215+
%5 = load %4 : $*UnsafeRawPointer
216+
return %5 : $UnsafeRawPointer
217+
}
218+
187219
// CHECK-LABEL: sil @load_first_char_from_string_literal
188220
// CHECK: bb0:
189221
// CHECK-NEXT: %0 = integer_literal $Builtin.Int8, 97

0 commit comments

Comments
 (0)