Skip to content

Commit 8d07096

Browse files
authored
Merge pull request #77618 from eeckstein/fix-rle
RedundantLoadElimination: correctly handle end_borrow instructions
2 parents 03319e5 + cea7da8 commit 8d07096

File tree

2 files changed

+47
-3
lines changed

2 files changed

+47
-3
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/RedundantLoadElimination.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -480,9 +480,14 @@ private struct InstructionScanner {
480480

481481
private mutating func visit(instruction: Instruction) -> ScanResult {
482482
switch instruction {
483-
case is FixLifetimeInst, is EndAccessInst, is BeginBorrowInst, is EndBorrowInst:
484-
return .transparent
485-
483+
case is FixLifetimeInst, is EndAccessInst, is EndBorrowInst:
484+
// Those scope-ending instructions are only irrelevant if the preceding load is not changed.
485+
// If it is changed from `load [copy]` -> `load [take]` the memory effects of those scope-ending
486+
// instructions prevent that the `load [take]` will illegally mutate memory which is protected
487+
// from mutation by the scope.
488+
if load.loadOwnership != .take {
489+
return .transparent
490+
}
486491
case let precedingLoad as LoadInst:
487492
if precedingLoad == load {
488493
// We need to stop the data flow analysis when we visit the original load again.

test/SILOptimizer/redundant_load_elim_ossa.sil

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ sil @use_2_64 : $@convention(thin) (Builtin.Int64, Builtin.Int64) -> ()
139139
sil @use_a : $@convention(thin) (A) -> ()
140140
sil @use_twofield : $@convention(thin) (TwoField) -> ()
141141
sil @init_twofield : $@convention(thin) (@thin TwoField.Type) -> TwoField
142+
sil @consumeB : $@convention(thin) (@owned B) -> ()
142143

143144
// We have a bug in the old projection code which this test case exposes.
144145
// Make sure its handled properly in the new projection.
@@ -1492,3 +1493,41 @@ bb0:
14921493
dealloc_stack %1 : $*Optional<B>
14931494
return %3 : $Optional<B>
14941495
}
1496+
1497+
// CHECK-LABEL: sil [ossa] @dont_take_in_borrow_scope :
1498+
// CHECK: load [copy]
1499+
// CHECK: end_borrow
1500+
// CHECK: load [take]
1501+
// CHECK-LABEL: } // end sil function 'dont_take_in_borrow_scope'
1502+
sil [ossa] @dont_take_in_borrow_scope : $@convention(thin) (@in B) -> () {
1503+
bb0(%0 : $*B):
1504+
%1 = load_borrow %0 : $*B
1505+
%2 = load [copy] %0 : $*B
1506+
%3 = function_ref @consumeB : $@convention(thin) (@owned B) -> ()
1507+
%4 = apply %3(%2) : $@convention(thin) (@owned B) -> ()
1508+
end_borrow %1 : $B
1509+
%6 = load [take] %0 : $*B
1510+
%7 = apply %3(%6) : $@convention(thin) (@owned B) -> ()
1511+
%8 = tuple ()
1512+
return %8 : $()
1513+
}
1514+
1515+
// CHECK-LABEL: sil [ossa] @copy_in_borrow_scope :
1516+
// CHECK: load [copy]
1517+
// CHECK: copy_value
1518+
// CHECK: end_borrow
1519+
// CHECK-NOT: load
1520+
// CHECK-LABEL: } // end sil function 'copy_in_borrow_scope'
1521+
sil [ossa] @copy_in_borrow_scope : $@convention(thin) (@inout B) -> () {
1522+
bb0(%0 : $*B):
1523+
%1 = load_borrow %0 : $*B
1524+
%2 = load [copy] %0 : $*B
1525+
%3 = function_ref @consumeB : $@convention(thin) (@owned B) -> ()
1526+
%4 = apply %3(%2) : $@convention(thin) (@owned B) -> ()
1527+
end_borrow %1 : $B
1528+
%6 = load [copy] %0 : $*B
1529+
%7 = apply %3(%6) : $@convention(thin) (@owned B) -> ()
1530+
%8 = tuple ()
1531+
return %8 : $()
1532+
}
1533+

0 commit comments

Comments
 (0)