Skip to content

Commit 972ac6f

Browse files
authored
Merge pull request #77610 from eeckstein/fix-array-element-propagation
ArrayElementValuePropagation: require that the initialization and element-get are in the same block for non-trivial values.
2 parents 8d07096 + 16c77d9 commit 972ac6f

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

lib/SILOptimizer/Transforms/ArrayElementValuePropagation.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,17 @@ bool ArrayAllocation::replaceGetElements() {
244244
if (EltValueIt == ElementValueMap.end())
245245
continue;
246246

247+
SILValue element = EltValueIt->second;
248+
249+
// In OSSA we only insert a copy_value of the element at the array initialization
250+
// point. This would result in an over-consume if the getElement is in a loop.
251+
// Therefore require that both semantic calls are in the same block.
252+
if (ArrayValue->getFunction()->hasOwnership() &&
253+
!element->getType().isTrivial(ArrayValue->getFunction()) &&
254+
ArrayValue->getParentBlock() != GetElementCall->getParent()) {
255+
continue;
256+
}
257+
247258
Changed |= GetElement.replaceByValue(EltValueIt->second);
248259
}
249260
return Changed;

test/SILOptimizer/array_element_propagation_crash.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,24 @@ func testit(_ arr: inout [Int]) {
1515
var a = [27]
1616
testit(&a)
1717

18+
// Second test case:
19+
var gg = ""
20+
21+
@inline(never)
22+
func use(_ s: String) {
23+
gg = s
24+
}
25+
26+
func testLoop() {
27+
let a = [""]
28+
29+
for _ in 0..<1000 {
30+
use(a[0])
31+
}
32+
}
33+
1834
// As a bonus, also check if the code works as expected.
1935
// CHECK: [27, 28]
2036
print(a)
2137

38+
testLoop()

0 commit comments

Comments
 (0)