Skip to content

Commit 5b8242f

Browse files
authored
Merge pull request #77915 from swiftlang/fix-aliasinfo-6.1
[6.1] AliasAnalysis: fix memory-behavior of closures with inout arguments
2 parents 81928fd + c4ac4c5 commit 5b8242f

File tree

3 files changed

+96
-0
lines changed

3 files changed

+96
-0
lines changed

SwiftCompilerSources/Sources/Optimizer/Analysis/AliasAnalysis.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,12 @@ private struct FullApplyEffectsVisitor : EscapeVisitorWithResult {
741741
return .ignore
742742
}
743743
if user == apply {
744+
if apply.isCallee(operand: operand) {
745+
// If the address "escapes" to the callee of the apply it means that the address was captured
746+
// by an inout_aliasable operand of an partial_apply.
747+
// Therefore assume that the called function will both, read and write, to the address.
748+
return .abort
749+
}
744750
let e = calleeAnalysis.getSideEffects(of: apply, operand: operand, path: path.projectionPath)
745751
result.merge(with: e)
746752
}

test/SILOptimizer/dead_store_elim.sil

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,3 +1692,21 @@ bb0(%0 : $Int, %1 : $Builtin.Int64, %2 : $Builtin.RawPointer):
16921692
return %r : $()
16931693
}
16941694

1695+
sil @closure_with_inout : $@convention(thin) (@inout_aliasable Int) -> ()
1696+
1697+
// CHECK-LABEL: sil @closure_with_inout_reads_argument :
1698+
// CHECK: store %0
1699+
// CHECK: end sil function 'closure_with_inout_reads_argument'
1700+
sil @closure_with_inout_reads_argument : $@convention(thin) (Int) -> () {
1701+
bb0(%0 : $Int):
1702+
%1 = alloc_stack $Int
1703+
store %0 to %1 : $*Int
1704+
%3 = function_ref @closure_with_inout : $@convention(thin) (@inout_aliasable Int) -> ()
1705+
%4 = partial_apply [callee_guaranteed] [on_stack] %3(%1) : $@convention(thin) (@inout_aliasable Int) -> ()
1706+
%50 = apply %4() : $@noescape @callee_guaranteed () -> ()
1707+
dealloc_stack %4 : $@noescape @callee_guaranteed () -> ()
1708+
dealloc_stack %1 : $*Int
1709+
%r = tuple ()
1710+
return %r : $()
1711+
}
1712+

test/SILOptimizer/mem-behavior.sil

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,78 @@ bb0(%0 : $*X):
16561656
return %3 : $()
16571657
}
16581658

1659+
sil @closure : $@convention(thin) (@inout_aliasable Int) -> ()
1660+
sil @closure2 : $@convention(thin) (Int, @inout_aliasable Int) -> ()
1661+
1662+
// CHECK-LABEL: @closure_with_inout
1663+
// CHECK: PAIR #0.
1664+
// CHECK-NEXT: %2 = partial_apply [callee_guaranteed] [on_stack] %1(%0) : $@convention(thin) (@inout_aliasable Int) -> ()
1665+
// CHECK-NEXT: %0 = argument of bb0 : $*Int
1666+
// CHECK-NEXT: r=0,w=0
1667+
// CHECK: PAIR #1.
1668+
// CHECK-NEXT: %3 = apply %2() : $@noescape @callee_guaranteed () -> ()
1669+
// CHECK-NEXT: %0 = argument of bb0 : $*Int
1670+
// CHECK-NEXT: r=1,w=1
1671+
sil @closure_with_inout : $@convention(thin) (@inout Int) -> () {
1672+
bb0(%0 : $*Int):
1673+
%1 = function_ref @closure : $@convention(thin) (@inout_aliasable Int) -> ()
1674+
%2 = partial_apply [callee_guaranteed] [on_stack] %1(%0) : $@convention(thin) (@inout_aliasable Int) -> ()
1675+
%3 = apply %2() : $@noescape @callee_guaranteed () -> ()
1676+
dealloc_stack %2 : $@noescape @callee_guaranteed () -> ()
1677+
%r = tuple ()
1678+
return %r : $()
1679+
}
1680+
1681+
// CHECK-LABEL: @two_closures_with_inout
1682+
// CHECK: PAIR #0.
1683+
// CHECK-NEXT: %3 = partial_apply [callee_guaranteed] [on_stack] %2(%0) : $@convention(thin) (Int, @inout_aliasable Int) -> ()
1684+
// CHECK-NEXT: %0 = argument of bb0 : $*Int
1685+
// CHECK-NEXT: r=0,w=0
1686+
// CHECK: PAIR #1.
1687+
// CHECK-NEXT: %4 = partial_apply [callee_guaranteed] [on_stack] %3(%1) : $@noescape @callee_guaranteed (Int) -> ()
1688+
// CHECK-NEXT: %0 = argument of bb0 : $*Int
1689+
// CHECK-NEXT: r=0,w=0
1690+
// CHECK: PAIR #2.
1691+
// CHECK-NEXT: %5 = apply %4() : $@noescape @callee_guaranteed () -> ()
1692+
// CHECK-NEXT: %0 = argument of bb0 : $*Int
1693+
// CHECK-NEXT: r=1,w=1
1694+
sil @two_closures_with_inout : $@convention(thin) (@inout Int, Int) -> () {
1695+
bb0(%0 : $*Int, %1 : $Int):
1696+
%2 = function_ref @closure2 : $@convention(thin) (Int, @inout_aliasable Int) -> ()
1697+
%3 = partial_apply [callee_guaranteed] [on_stack] %2(%0) : $@convention(thin) (Int, @inout_aliasable Int) -> ()
1698+
%4 = partial_apply [callee_guaranteed] [on_stack] %3(%1) : $@noescape @callee_guaranteed (Int) -> ()
1699+
%5 = apply %4() : $@noescape @callee_guaranteed () -> ()
1700+
dealloc_stack %4 : $@noescape @callee_guaranteed () -> ()
1701+
dealloc_stack %3 : $@noescape @callee_guaranteed (Int) -> ()
1702+
%r = tuple ()
1703+
return %r : $()
1704+
}
1705+
1706+
sil @call_closure : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> () {
1707+
[%0: read v**.c*.v**, write v**.c*.v**]
1708+
[global: read,write]
1709+
}
1710+
1711+
// CHECK-LABEL: @pass_closure_to_function
1712+
// CHECK: PAIR #0.
1713+
// CHECK-NEXT: %2 = partial_apply [callee_guaranteed] [on_stack] %1(%0) : $@convention(thin) (@inout_aliasable Int) -> ()
1714+
// CHECK-NEXT: %0 = argument of bb0 : $*Int
1715+
// CHECK-NEXT: r=0,w=0
1716+
// CHECK: PAIR #1.
1717+
// CHECK-NEXT: %4 = apply %3(%2) : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
1718+
// CHECK-NEXT: %0 = argument of bb0 : $*Int
1719+
// CHECK-NEXT: r=1,w=1
1720+
sil @pass_closure_to_function : $@convention(thin) (@inout Int) -> () {
1721+
bb0(%0 : $*Int):
1722+
%4 = function_ref @closure : $@convention(thin) (@inout_aliasable Int) -> ()
1723+
%5 = partial_apply [callee_guaranteed] [on_stack] %4(%0) : $@convention(thin) (@inout_aliasable Int) -> ()
1724+
%6 = function_ref @call_closure : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
1725+
%7 = apply %6(%5) : $@convention(thin) (@guaranteed @noescape @callee_guaranteed () -> ()) -> ()
1726+
dealloc_stack %5 : $@noescape @callee_guaranteed () -> ()
1727+
%r = tuple ()
1728+
return %r : $()
1729+
}
1730+
16591731
// CHECK-LABEL: @test_is_unique
16601732
// CHECK: PAIR #0.
16611733
// CHECK-NEXT: %2 = is_unique %0 : $*X

0 commit comments

Comments
 (0)