Skip to content

Commit 4d1d688

Browse files
authored
Merge pull request swiftlang#87336 from Azoy/ensure-end-borrow
[SILCombine] Ensure we emit an end_borrow after simplifying init_borrow_addr
2 parents 5ed27ff + 4cf8588 commit 4d1d688

File tree

5 files changed

+92
-43
lines changed

5 files changed

+92
-43
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyBorrow.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ extension InitBorrowAddrInst: OnoneSimplifiable, SILCombineSimplifiable {
3434

3535
let builder = Builder(before: self, context)
3636

37-
let newBorrow: Value
37+
let newBorrow: MakeBorrowInstruction
3838

3939
// If our referent is loadable, then rewrite:
4040
//
@@ -43,6 +43,7 @@ extension InitBorrowAddrInst: OnoneSimplifiable, SILCombineSimplifiable {
4343
// %referent = load_borrow %referent_addr
4444
// %borrow = make_borrow %referent
4545
// store %borrow to %borrow_addr
46+
// end_borrow %referent
4647
//
4748
// Otherwise, our referent is address only for borrows, so rewrite uses into
4849
// the address form:
@@ -52,9 +53,13 @@ extension InitBorrowAddrInst: OnoneSimplifiable, SILCombineSimplifiable {
5253
// %borrow = make_addr_borrow %referent_addr
5354
// store %borrow to %borrow_addr
5455
//
56+
var emittedLoadBorrow = false
57+
5558
if loadable {
5659
let loadedReferent = builder.emitLoadBorrow(fromAddress: referent)
5760
newBorrow = builder.createMakeBorrow(referent: loadedReferent)
61+
62+
emittedLoadBorrow = loadedReferent is LoadBorrowInst
5863
} else {
5964
newBorrow = builder.createMakeAddrBorrow(referent: referent)
6065
}
@@ -71,6 +76,10 @@ extension InitBorrowAddrInst: OnoneSimplifiable, SILCombineSimplifiable {
7176
ownership: storeOwnership
7277
)
7378

79+
if emittedLoadBorrow {
80+
builder.createEndBorrow(of: newBorrow.referent)
81+
}
82+
7483
context.erase(instruction: self)
7584
}
7685
}

SwiftCompilerSources/Sources/SIL/Instruction.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,13 +2185,20 @@ final public class IgnoredUseInst : Instruction, UnaryInstruction {
21852185
final public class ImplicitActorToOpaqueIsolationCastInst
21862186
: SingleValueInstruction, UnaryInstruction {}
21872187

2188-
final public class MakeBorrowInst
2188+
public protocol MakeBorrowInstruction
21892189
: SingleValueInstruction, UnaryInstruction {
2190+
var referent: Value { get }
2191+
}
2192+
2193+
extension MakeBorrowInstruction {
21902194
public var referent: Value {
21912195
operands[0].value
21922196
}
21932197
}
21942198

2199+
final public class MakeBorrowInst
2200+
: SingleValueInstruction, MakeBorrowInstruction, UnaryInstruction {}
2201+
21952202
final public class DereferenceBorrowInst
21962203
: SingleValueInstruction, UnaryInstruction {
21972204
public var borrow: Value {
@@ -2200,11 +2207,7 @@ final public class DereferenceBorrowInst
22002207
}
22012208

22022209
final public class MakeAddrBorrowInst
2203-
: SingleValueInstruction, UnaryInstruction {
2204-
public var referent: Value {
2205-
operands[0].value
2206-
}
2207-
}
2210+
: SingleValueInstruction, MakeBorrowInstruction, UnaryInstruction {}
22082211

22092212
final public class DereferenceAddrBorrowInst
22102213
: SingleValueInstruction, UnaryInstruction {

test/SILOptimizer/sil_combine.sil

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -4361,41 +4361,6 @@ sil @test_type_value_concrete_negative : $@convention(thin) () -> Int {
43614361
return %val : $Int
43624362
}
43634363

4364-
// CHECK-LABEL: sil @test_init_borrow_addr_generic : $@convention(thin) <T> (@in_guaranteed T) -> @out Builtin.Borrow<T> {
4365-
// CHECK: init_borrow_addr %0 : $*Builtin.Borrow<T> with %1 : $*T
4366-
// CHECK-LABEL: } // end sil function 'test_init_borrow_addr_generic'
4367-
sil @test_init_borrow_addr_generic : $@convention(thin) <T> (@in_guaranteed T) -> @out Builtin.Borrow<T> {
4368-
bb0(%0 : $*Builtin.Borrow<T>, %1 : $*T):
4369-
init_borrow_addr %0 : $*Builtin.Borrow<T> with %1 : $*T
4370-
%r = tuple ()
4371-
return %r : $()
4372-
}
4373-
4374-
// CHECK-LABEL: sil @test_init_borrow_addr_loadable : $@convention(thin) (@in_guaranteed Int) -> @out Builtin.Borrow<Int> {
4375-
// CHECK-NOT: init_borrow_addr
4376-
// CHECK: [[LOADED_INT:%.*]] = load %1 : $*Int
4377-
// CHECK: [[BORROW:%.*]] = make_borrow [[LOADED_INT]]
4378-
// CHECK: store [[BORROW]] to %0 : $*Builtin.Borrow<Int>
4379-
// CHECK-LABEL: } // end sil function 'test_init_borrow_addr_loadable'
4380-
sil @test_init_borrow_addr_loadable : $@convention(thin) (@in_guaranteed Int) -> @out Builtin.Borrow<Int> {
4381-
bb0(%0 : $*Builtin.Borrow<Int>, %1 : $*Int):
4382-
init_borrow_addr %0 : $*Builtin.Borrow<Int> with %1 : $*Int
4383-
%r = tuple ()
4384-
return %r : $()
4385-
}
4386-
4387-
// CHECK-LABEL: sil @test_init_borrow_addr_addressonly : $@convention(thin) (@in_guaranteed AddressOnlyEnum) -> @out Builtin.Borrow<AddressOnlyEnum> {
4388-
// CHECK-NOT: init_borrow_addr
4389-
// CHECK: [[BORROW:%.*]] = make_addr_borrow %1 : $*AddressOnlyEnum
4390-
// CHECK: store [[BORROW]] to %0 : $*Builtin.Borrow<AddressOnlyEnum>
4391-
// CHECK-LABEL: } // end sil function 'test_init_borrow_addr_addressonly'
4392-
sil @test_init_borrow_addr_addressonly : $@convention(thin) (@in_guaranteed AddressOnlyEnum) -> @out Builtin.Borrow<AddressOnlyEnum> {
4393-
bb0(%0 : $*Builtin.Borrow<AddressOnlyEnum>, %1 : $*AddressOnlyEnum):
4394-
init_borrow_addr %0 : $*Builtin.Borrow<AddressOnlyEnum> with %1 : $*AddressOnlyEnum
4395-
%r = tuple ()
4396-
return %r : $()
4397-
}
4398-
43994364
// CHECK-LABEL: sil @test_dereference_borrow : $@convention(thin) (Int) -> Int {
44004365
// CHECK: bb0([[INT:%.*]] : $Int):
44014366
// CHECK-NEXT: return [[INT]] : $Int
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -onone-simplification -simplify-instruction=init_borrow_addr | %FileCheck %s
2+
3+
// REQUIRES: swift_in_compiler
4+
5+
// Declare this SIL to be canonical because some tests break raw SIL
6+
// conventions. e.g. address-type block args. -enforce-exclusivity=none is also
7+
// required to allow address-type block args in canonical SIL.
8+
sil_stage canonical
9+
10+
import Builtin
11+
import Swift
12+
13+
enum AddressOnlyEnum {
14+
case Loadable(Builtin.Int32)
15+
case AddressOnly(Any)
16+
}
17+
18+
struct MyInt {
19+
var value: Builtin.Int32
20+
}
21+
22+
struct MoveOnlyStruct: ~Copyable {
23+
var value: MyInt
24+
}
25+
26+
// CHECK-LABEL: sil @test_init_borrow_addr_generic : $@convention(thin) <T> (@in_guaranteed T) -> @out Builtin.Borrow<T> {
27+
// CHECK: init_borrow_addr %0 : $*Builtin.Borrow<T> with %1 : $*T
28+
// CHECK-LABEL: } // end sil function 'test_init_borrow_addr_generic'
29+
sil @test_init_borrow_addr_generic : $@convention(thin) <T> (@in_guaranteed T) -> @out Builtin.Borrow<T> {
30+
bb0(%0 : $*Builtin.Borrow<T>, %1 : $*T):
31+
init_borrow_addr %0 : $*Builtin.Borrow<T> with %1 : $*T
32+
%r = tuple ()
33+
return %r : $()
34+
}
35+
36+
// CHECK-LABEL: sil @test_init_borrow_addr_loadable : $@convention(thin) (@in_guaranteed Int) -> @out Builtin.Borrow<Int> {
37+
// CHECK-NOT: init_borrow_addr
38+
// CHECK: [[LOADED_INT:%.*]] = load %1 : $*Int
39+
// CHECK: [[BORROW:%.*]] = make_borrow [[LOADED_INT]]
40+
// CHECK: store [[BORROW]] to %0 : $*Builtin.Borrow<Int>
41+
// CHECK-LABEL: } // end sil function 'test_init_borrow_addr_loadable'
42+
sil @test_init_borrow_addr_loadable : $@convention(thin) (@in_guaranteed Int) -> @out Builtin.Borrow<Int> {
43+
bb0(%0 : $*Builtin.Borrow<Int>, %1 : $*Int):
44+
init_borrow_addr %0 : $*Builtin.Borrow<Int> with %1 : $*Int
45+
%r = tuple ()
46+
return %r : $()
47+
}
48+
49+
// CHECK-LABEL: sil @test_init_borrow_addr_addressonly : $@convention(thin) (@in_guaranteed AddressOnlyEnum) -> @out Builtin.Borrow<AddressOnlyEnum> {
50+
// CHECK-NOT: init_borrow_addr
51+
// CHECK: [[BORROW:%.*]] = make_addr_borrow %1 : $*AddressOnlyEnum
52+
// CHECK: store [[BORROW]] to %0 : $*Builtin.Borrow<AddressOnlyEnum>
53+
// CHECK-LABEL: } // end sil function 'test_init_borrow_addr_addressonly'
54+
sil @test_init_borrow_addr_addressonly : $@convention(thin) (@in_guaranteed AddressOnlyEnum) -> @out Builtin.Borrow<AddressOnlyEnum> {
55+
bb0(%0 : $*Builtin.Borrow<AddressOnlyEnum>, %1 : $*AddressOnlyEnum):
56+
init_borrow_addr %0 : $*Builtin.Borrow<AddressOnlyEnum> with %1 : $*AddressOnlyEnum
57+
%r = tuple ()
58+
return %r : $()
59+
}
60+
61+
// CHECK-LABEL: sil [ossa] @test_init_borrow_addr_ossa : $@convention(thin) (@in_guaranteed MoveOnlyStruct) -> @out Builtin.Borrow<MoveOnlyStruct> {
62+
// CHECK-NOT: init_borrow_addr
63+
// CHECK: [[LOADED:%.*]] = load_borrow %1 : $*MoveOnlyStruct
64+
// CHECK: [[BORROW:%.*]] = make_borrow [[LOADED]]
65+
// CHECK: store [[BORROW]] to [trivial] %0 : $*Builtin.Borrow<MoveOnlyStruct>
66+
// CHECK: end_borrow [[LOADED]]
67+
// CHECK-LABEL: } // end sil function 'test_init_borrow_addr_ossa'
68+
sil [ossa] @test_init_borrow_addr_ossa : $@convention(thin) (@in_guaranteed MoveOnlyStruct) -> @out Builtin.Borrow<MoveOnlyStruct> {
69+
bb0(%0 : $*Builtin.Borrow<MoveOnlyStruct>, %1 : $*MoveOnlyStruct):
70+
init_borrow_addr %0 : $*Builtin.Borrow<MoveOnlyStruct> with %1 : $*MoveOnlyStruct
71+
%r = tuple ()
72+
return %r : $()
73+
}

test/SILOptimizer/sil_combine_ossa.sil

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5664,4 +5664,3 @@ bb2:
56645664
destroy_value [dead_end] %0
56655665
unreachable
56665666
}
5667-

0 commit comments

Comments
 (0)