Skip to content

Commit c3a08f0

Browse files
authored
Merge pull request #29249 from atrick/fix-stackpromote
Fix EscapeAnalysis losing precision during merge.
2 parents 1370f8f + fbe38ce commit c3a08f0

File tree

2 files changed

+7
-47
lines changed

2 files changed

+7
-47
lines changed

lib/SILOptimizer/Analysis/EscapeAnalysis.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -732,9 +732,13 @@ void EscapeAnalysis::ConnectionGraph::mergeAllScheduledNodes() {
732732
From->isMerged = true;
733733

734734
if (From->mappedValue) {
735-
if (To->mappedValue)
736-
Values2Nodes.erase(From->mappedValue);
737-
else {
735+
// If possible, transfer 'From's mappedValue to 'To' for clarity. Any
736+
// values previously mapped to 'From' but not transferred to 'To's
737+
// mappedValue must remain mapped to 'From'. Lookups on those values will
738+
// find 'To' via the mergeTarget. Dropping a value's mapping is illegal
739+
// because it could cause a node to be recreated without the edges that
740+
// have already been discovered.
741+
if (!To->mappedValue) {
738742
To->mappedValue = From->mappedValue;
739743
Values2Nodes[To->mappedValue] = To;
740744
}

test/SILOptimizer/escape_analysis.sil

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1817,47 +1817,3 @@ bb0(%0 : $IntWrapper):
18171817
%tuple = tuple (%bridge : $Builtin.BridgeObject, %ump : $UnsafeMutablePointer<Int64>)
18181818
return %tuple : $(Builtin.BridgeObject, UnsafeMutablePointer<Int64>)
18191819
}
1820-
1821-
// =============================================================================
1822-
// Test call to array.uninitialized that has extra release_value uses
1823-
1824-
class DummyArrayStorage<Element> {
1825-
@_hasStorage var count: Int { get }
1826-
@_hasStorage var capacity: Int { get }
1827-
init()
1828-
}
1829-
1830-
// init_any_array_with_buffer
1831-
sil [_semantics "array.uninitialized"] @init_any_array_with_buffer : $@convention(thin) (@owned DummyArrayStorage<AnyObject>, Int32, @thin Array<AnyObject>.Type) -> (@owned Array<AnyObject>, UnsafeMutablePointer<AnyObject>)
1832-
1833-
// CHECK-LABEL: CG of testBadArrayUninit
1834-
// CHECK-NEXT: Val [ref] %2 Esc: , Succ: (%2.1)
1835-
// CHECK-NEXT: Con [int] %2.1 Esc: G, Succ: (%2.2)
1836-
// CHECK-NEXT: Con [ref] %2.2 Esc: G, Succ:
1837-
// CHECK-NEXT: Val %5 Esc: , Succ: (%5.1)
1838-
// CHECK-NEXT: Con %5.1 Esc: G, Succ: %10
1839-
// CHECK-NEXT: Val [ref] %10 Esc: G, Succ: (%10.1)
1840-
// CHECK-NEXT: Con %10.1 Esc: G, Succ:
1841-
// CHECK-LABEL: End
1842-
sil hidden @testBadArrayUninit : $@convention(thin) (Builtin.Word, Int32) -> () {
1843-
bb0(%0 : $Builtin.Word, %1 : $Int32):
1844-
// create an array
1845-
%2 = alloc_ref [tail_elems $AnyObject * %0 : $Builtin.Word] $DummyArrayStorage<AnyObject>
1846-
%3 = metatype $@thin Array<AnyObject>.Type
1847-
%4 = function_ref @init_any_array_with_buffer : $@convention(thin) (@owned DummyArrayStorage<AnyObject>, Int32, @thin Array<AnyObject>.Type) -> (@owned Array<AnyObject>, UnsafeMutablePointer<AnyObject>)
1848-
%5 = apply %4(%2, %1, %3) : $@convention(thin) (@owned DummyArrayStorage<AnyObject>, Int32, @thin Array<AnyObject>.Type) -> (@owned Array<AnyObject>, UnsafeMutablePointer<AnyObject>)
1849-
%6 = tuple_extract %5 : $(Array<AnyObject>, UnsafeMutablePointer<AnyObject>), 0
1850-
%7 = tuple_extract %5 : $(Array<AnyObject>, UnsafeMutablePointer<AnyObject>), 1
1851-
%8 = struct_extract %7 : $UnsafeMutablePointer<AnyObject>, #UnsafeMutablePointer._rawValue
1852-
%9 = pointer_to_address %8 : $Builtin.RawPointer to [strict] $*AnyObject
1853-
1854-
// store an elt
1855-
%10 = alloc_ref $C
1856-
%11 = init_existential_ref %10 : $C : $C, $AnyObject
1857-
store %11 to %9 : $*AnyObject
1858-
1859-
// extra use of the call
1860-
release_value %5 : $(Array<AnyObject>, UnsafeMutablePointer<AnyObject>) // id: %228
1861-
%13 = tuple ()
1862-
return %13 : $()
1863-
}

0 commit comments

Comments
 (0)