Skip to content

Commit 824a71d

Browse files
authored
Merge pull request #29466 from atrick/fix-escape-verify
Fix EscapeAnalysis verification for an array.uninitialized case.
2 parents 37e267f + c881a4f commit 824a71d

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

lib/SILOptimizer/Analysis/EscapeAnalysis.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -1822,13 +1822,16 @@ EscapeAnalysis::canOptimizeArrayUninitializedCall(
18221822

18231823
// Check if the result is used in the usual way: extracting the
18241824
// array and the element pointer with tuple_extract.
1825+
//
1826+
// Do not ignore any uses, even redundant tuple_extract, because all apply
1827+
// uses must be mapped to ConnectionGraph nodes by the client of this API.
18251828
for (Operand *use : getNonDebugUses(ai)) {
18261829
if (auto *tei = dyn_cast<TupleExtractInst>(use->getUser())) {
1827-
if (tei->getFieldNo() == 0) {
1830+
if (tei->getFieldNo() == 0 && !call.arrayStruct) {
18281831
call.arrayStruct = tei;
18291832
continue;
18301833
}
1831-
if (tei->getFieldNo() == 1) {
1834+
if (tei->getFieldNo() == 1 && !call.arrayElementPtr) {
18321835
call.arrayElementPtr = tei;
18331836
continue;
18341837
}

test/SILOptimizer/escape_analysis_reduced.sil

+33
Original file line numberDiff line numberDiff line change
@@ -559,3 +559,36 @@ bb65(%614 : $Error):
559559
bb72(%681 : $Error):
560560
throw %681 : $Error
561561
}
562+
563+
//=============================================================================
564+
// Test an "array.uninitialized" with multiple tuple_extract's but no
565+
// other unusual uses. Make sure canOptimizeArrayUninitializedCall
566+
// returns false; otherwise graph verification can fail because only
567+
// one of the tuple_extracts is mapped to a node.
568+
569+
// specialized static Array._adoptStorage(_:count:)
570+
sil [_semantics "array.uninitialized"] @$sSa13_adoptStorage_5countSayxG_SpyxGts016_ContiguousArrayB0CyxGn_SitFZSo5Int64V_Tg5 : $@convention(method) (@owned _ContiguousArrayStorage<Int64>, Int, @thin Array<Int64>.Type) -> (@owned Array<Int64>, UnsafeMutablePointer<Int64>)
571+
572+
// CHECK-LABEL: CG of testArrayUninitResultMapping
573+
// CHECK-NEXT: [ref] %0 Esc: , Succ: (%0.1)
574+
// CHECK-NEXT: Con [int] %0.1 Esc: G, Succ: (%0.2)
575+
// CHECK-NEXT: Con [ref] %0.2 Esc: G, Succ:
576+
// CHECK-NEXT: Val %2 Esc: , Succ: (%2.1)
577+
// CHECK-NEXT: Con %2.1 Esc: G, Succ:
578+
// CHECK-LABEL: End
579+
sil hidden @testArrayUninitResultMapping : $@convention(thin) () -> () {
580+
bb0:
581+
%0 = alloc_ref [tail_elems $Int64 * undef : $Builtin.Word] $_ContiguousArrayStorage<Int64>
582+
// function_ref specialized static Array._adoptStorage(_:count:)
583+
%1 = function_ref @$sSa13_adoptStorage_5countSayxG_SpyxGts016_ContiguousArrayB0CyxGn_SitFZSo5Int64V_Tg5 : $@convention(method) (@owned _ContiguousArrayStorage<Int64>, Int, @thin Array<Int64>.Type) -> (@owned Array<Int64>, UnsafeMutablePointer<Int64>)
584+
%2 = apply %1(%0, undef, undef) : $@convention(method) (@owned _ContiguousArrayStorage<Int64>, Int, @thin Array<Int64>.Type) -> (@owned Array<Int64>, UnsafeMutablePointer<Int64>)
585+
%3 = tuple_extract %2 : $(Array<Int64>, UnsafeMutablePointer<Int64>), 0
586+
%4 = tuple_extract %2 : $(Array<Int64>, UnsafeMutablePointer<Int64>), 1
587+
%5 = tuple_extract %2 : $(Array<Int64>, UnsafeMutablePointer<Int64>), 0
588+
%6 = struct_extract %5 : $Array<Int64>, #Array._buffer
589+
%7 = struct_extract %6 : $_ArrayBuffer<Int64>, #_ArrayBuffer._storage
590+
%8 = struct_extract %7 : $_BridgeStorage<__ContiguousArrayStorageBase>, #_BridgeStorage.rawValue
591+
strong_retain %8 : $Builtin.BridgeObject
592+
%10 = tuple ()
593+
return %10 : $()
594+
}

0 commit comments

Comments
 (0)