Skip to content

Commit 196994f

Browse files
committedAug 16, 2022
Fix store_borrow generation in SILGen
This change ensures all store_borrows are ended with an end_borrow, and uses of the store_borrow destination are all in the enclosing store_borrow scope and via the store_borrow return address. Fix tests to reflect new store_borrow pattern

34 files changed

+256
-250
lines changed
 

‎lib/SILGen/ManagedValue.cpp

+30-3
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ ManagedValue ManagedValue::materialize(SILGenFunction &SGF,
200200
auto temporary = SGF.emitTemporaryAllocation(loc, getType());
201201
bool hadCleanup = hasCleanup();
202202

203-
// The temporary memory is +0 if the value was.
204203
if (hadCleanup) {
205204
SGF.B.emitStoreValueOperation(loc, forward(SGF), temporary,
206205
StoreOwnershipQualifier::Init);
@@ -218,9 +217,37 @@ ManagedValue ManagedValue::materialize(SILGenFunction &SGF,
218217
return ManagedValue::forOwnedAddressRValue(
219218
temporary, SGF.enterDestroyCleanup(temporary));
220219
}
220+
// The temporary memory is +0 if the value was.
221221
auto object = SGF.emitManagedBeginBorrow(loc, getValue());
222-
SGF.emitManagedStoreBorrow(loc, object.getValue(), temporary);
223-
return ManagedValue::forBorrowedAddressRValue(temporary);
222+
auto borrowedAddr =
223+
SGF.emitManagedStoreBorrow(loc, object.getValue(), temporary);
224+
return ManagedValue::forBorrowedAddressRValue(borrowedAddr.getValue());
225+
}
226+
227+
ManagedValue ManagedValue::formallyMaterialize(SILGenFunction &SGF,
228+
SILLocation loc) const {
229+
auto temporary = SGF.emitTemporaryAllocation(loc, getType());
230+
bool hadCleanup = hasCleanup();
231+
auto &lowering = SGF.getTypeLowering(getType());
232+
233+
if (hadCleanup) {
234+
SGF.B.emitStoreValueOperation(loc, forward(SGF), temporary,
235+
StoreOwnershipQualifier::Init);
236+
237+
return ManagedValue::forOwnedAddressRValue(
238+
temporary, SGF.enterDestroyCleanup(temporary));
239+
}
240+
if (lowering.isAddressOnly()) {
241+
assert(!SGF.silConv.useLoweredAddresses());
242+
auto copy = SGF.B.createCopyValue(loc, getValue());
243+
SGF.B.emitStoreValueOperation(loc, copy, temporary,
244+
StoreOwnershipQualifier::Init);
245+
return ManagedValue::forOwnedAddressRValue(
246+
temporary, SGF.enterDestroyCleanup(temporary));
247+
}
248+
auto object = SGF.emitFormalEvaluationManagedBeginBorrow(loc, getValue());
249+
return SGF.emitFormalEvaluationManagedStoreBorrow(loc, object.getValue(),
250+
temporary);
224251
}
225252

226253
void ManagedValue::print(raw_ostream &os) const {

‎lib/SILGen/ManagedValue.h

+2
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,8 @@ class ManagedValue {
320320
/// exact same level of cleanup it had before.
321321
ManagedValue materialize(SILGenFunction &SGF, SILLocation loc) const;
322322

323+
ManagedValue formallyMaterialize(SILGenFunction &SGF, SILLocation loc) const;
324+
323325
/// Disable the cleanup for this value.
324326
void forwardCleanup(SILGenFunction &SGF) const;
325327

‎lib/SILGen/SILGenApply.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -5722,7 +5722,11 @@ ArgumentSource AccessorBaseArgPreparer::prepareAccessorObjectBaseArg() {
57225722
assert(!selfParam.isIndirectMutating() &&
57235723
"passing unmaterialized r-value as inout argument");
57245724

5725-
base = base.materialize(SGF, loc);
5725+
base = base.formallyMaterialize(SGF, loc);
5726+
auto shouldTake = IsTake_t(base.hasCleanup());
5727+
base = SGF.emitFormalAccessLoad(loc, base.forward(SGF),
5728+
SGF.getTypeLowering(baseLoweredType),
5729+
SGFContext(), shouldTake);
57265730
}
57275731

57285732
return ArgumentSource(loc, RValue(SGF, loc, baseFormalType, base));

‎lib/SILGen/SILGenBridging.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ emitBridgeNativeToObjectiveC(SILGenFunction &SGF,
154154
if (witnessConv.isSILIndirect(witnessConv.getParameters()[0])
155155
&& !swiftValue.getType().isAddress()) {
156156
auto tmp = SGF.emitTemporaryAllocation(loc, swiftValue.getType());
157-
SGF.B.createStoreBorrowOrTrivial(loc, swiftValue.borrow(SGF, loc), tmp);
158-
swiftValue = ManagedValue::forUnmanaged(tmp);
157+
swiftValue = SGF.emitManagedStoreBorrow(
158+
loc, swiftValue.borrow(SGF, loc).getValue(), tmp);
159159
}
160160

161161
// Call the witness.

‎lib/SILGen/SILGenBuilder.cpp

+10-8
Original file line numberDiff line numberDiff line change
@@ -721,21 +721,23 @@ createValueMetatype(SILLocation loc, SILType metatype,
721721
return ManagedValue::forUnmanaged(v);
722722
}
723723

724-
void SILGenBuilder::createStoreBorrow(SILLocation loc, ManagedValue value,
725-
SILValue address) {
724+
ManagedValue SILGenBuilder::createStoreBorrow(SILLocation loc,
725+
ManagedValue value,
726+
SILValue address) {
726727
assert(value.getOwnershipKind() == OwnershipKind::Guaranteed);
727-
createStoreBorrow(loc, value.getValue(), address);
728+
auto *sbi = createStoreBorrow(loc, value.getValue(), address);
729+
return ManagedValue(sbi, CleanupHandle::invalid());
728730
}
729731

730-
void SILGenBuilder::createStoreBorrowOrTrivial(SILLocation loc,
731-
ManagedValue value,
732-
SILValue address) {
732+
ManagedValue SILGenBuilder::createStoreBorrowOrTrivial(SILLocation loc,
733+
ManagedValue value,
734+
SILValue address) {
733735
if (value.getOwnershipKind() == OwnershipKind::None) {
734736
createStore(loc, value, address, StoreOwnershipQualifier::Trivial);
735-
return;
737+
return ManagedValue(address, CleanupHandle::invalid());
736738
}
737739

738-
createStoreBorrow(loc, value, address);
740+
return createStoreBorrow(loc, value, address);
739741
}
740742

741743
ManagedValue SILGenBuilder::createBridgeObjectToRef(SILLocation loc,

‎lib/SILGen/SILGenBuilder.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,13 @@ class SILGenBuilder : public SILBuilder {
190190
ManagedValue createFormalAccessLoadBorrow(SILLocation loc, ManagedValue base);
191191

192192
using SILBuilder::createStoreBorrow;
193-
void createStoreBorrow(SILLocation loc, ManagedValue value, SILValue address);
193+
ManagedValue createStoreBorrow(SILLocation loc, ManagedValue value,
194+
SILValue address);
194195

195196
/// Create a store_borrow if we have a non-trivial value and a store [trivial]
196197
/// otherwise.
197-
void createStoreBorrowOrTrivial(SILLocation loc, ManagedValue value,
198-
SILValue address);
198+
ManagedValue createStoreBorrowOrTrivial(SILLocation loc, ManagedValue value,
199+
SILValue address);
199200

200201
/// Prepares a buffer to receive the result of an expression, either using the
201202
/// 'emit into' initialization buffer if available, or allocating a temporary

‎lib/SILGen/SILGenExpr.cpp

+16-10
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,13 @@ ManagedValue SILGenFunction::emitManagedStoreBorrow(
129129
assert(lowering.getLoweredType().getObjectType() == v->getType());
130130
if (lowering.isTrivial() || v->getOwnershipKind() == OwnershipKind::None) {
131131
lowering.emitStore(B, loc, v, addr, StoreOwnershipQualifier::Trivial);
132-
return ManagedValue::forUnmanaged(v);
132+
return ManagedValue::forTrivialAddressRValue(addr);
133133
}
134134
assert((!lowering.isAddressOnly() || !silConv.useLoweredAddresses()) &&
135135
"cannot retain an unloadable type");
136136
auto *sbi = B.createStoreBorrow(loc, v, addr);
137-
return emitManagedBorrowedRValueWithCleanup(sbi->getSrc(), sbi, lowering);
137+
Cleanups.pushCleanup<EndBorrowCleanup>(sbi);
138+
return ManagedValue(sbi, CleanupHandle::invalid());
138139
}
139140

140141
ManagedValue SILGenFunction::emitManagedBeginBorrow(SILLocation loc,
@@ -243,6 +244,18 @@ ManagedValue SILGenFunction::emitFormalEvaluationManagedBeginBorrow(
243244
lowering);
244245
}
245246

247+
ManagedValue SILGenFunction::emitFormalEvaluationManagedStoreBorrow(
248+
SILLocation loc, SILValue v, SILValue addr) {
249+
auto &lowering = getTypeLowering(v->getType());
250+
if (lowering.isTrivial() || v->getOwnershipKind() == OwnershipKind::None) {
251+
lowering.emitStore(B, loc, v, addr, StoreOwnershipQualifier::Trivial);
252+
return ManagedValue::forTrivialAddressRValue(addr);
253+
}
254+
auto *sbi = B.createStoreBorrow(loc, v, addr);
255+
return emitFormalEvaluationManagedBorrowedRValueWithCleanup(loc, v, sbi,
256+
lowering);
257+
}
258+
246259
ManagedValue
247260
SILGenFunction::emitFormalEvaluationManagedBorrowedRValueWithCleanup(
248261
SILLocation loc, SILValue original, SILValue borrowed) {
@@ -260,10 +273,6 @@ SILGenFunction::emitFormalEvaluationManagedBorrowedRValueWithCleanup(
260273
if (lowering.isTrivial())
261274
return ManagedValue::forUnmanaged(borrowed);
262275

263-
if (!borrowed->getType().isObject()) {
264-
return ManagedValue(borrowed, CleanupHandle::invalid());
265-
}
266-
267276
assert(isInFormalEvaluationScope() && "Must be in formal evaluation scope");
268277
auto &cleanup = Cleanups.pushCleanup<FormalEvaluationEndBorrowCleanup>();
269278
CleanupHandle handle = Cleanups.getTopCleanup();
@@ -329,10 +338,7 @@ ManagedValue SILGenFunction::emitManagedBorrowedRValueWithCleanup(
329338
original->getOwnershipKind() == OwnershipKind::None)
330339
return ManagedValue::forUnmanaged(borrowed);
331340

332-
if (borrowed->getType().isObject()) {
333-
Cleanups.pushCleanup<EndBorrowCleanup>(borrowed);
334-
}
335-
341+
Cleanups.pushCleanup<EndBorrowCleanup>(borrowed);
336342
return ManagedValue(borrowed, CleanupHandle::invalid());
337343
}
338344

‎lib/SILGen/SILGenFunction.h

+4
Original file line numberDiff line numberDiff line change
@@ -1544,6 +1544,10 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
15441544
emitFormalEvaluationManagedBeginBorrow(SILLocation loc, SILValue v,
15451545
const TypeLowering &lowering);
15461546

1547+
ManagedValue emitFormalEvaluationManagedStoreBorrow(SILLocation loc,
1548+
SILValue v,
1549+
SILValue addr);
1550+
15471551
ManagedValue emitManagedRValueWithCleanup(SILValue v);
15481552
ManagedValue emitManagedRValueWithCleanup(SILValue v,
15491553
const TypeLowering &lowering);

‎test/SIL/OwnershipVerifier/false_positive_leaks.sil

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ sil [ossa] @leak_loop_test : $@convention(thin) (@owned Builtin.NativeObject) ->
2626
bb0(%0 : @owned $Builtin.NativeObject):
2727
%1 = alloc_stack $Builtin.NativeObject
2828
%2 = begin_borrow %0 : $Builtin.NativeObject
29-
store_borrow %2 to %1 : $*Builtin.NativeObject
29+
%sbi = store_borrow %2 to %1 : $*Builtin.NativeObject
3030
%3 = function_ref @in_guaranteed_user : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
31-
apply %3(%1) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
31+
apply %3(%sbi) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
32+
end_borrow %sbi : $*Builtin.NativeObject
3233
end_borrow %2 : $Builtin.NativeObject
3334
dealloc_stack %1 : $*Builtin.NativeObject
3435
br bb1

‎test/SIL/OwnershipVerifier/interior_pointer.sil

+2-2
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,7 @@ bb0(%0 : @owned $Box<T>, %1 : $*Int):
119119
// CHECK-NEXT: Found outside of lifetime use?!
120120
// CHECK-NEXT: Value: %1 = begin_borrow %0 : $Builtin.NativeObject // users: %4, %3
121121
// CHECK-NEXT: Consuming User: end_borrow %1 : $Builtin.NativeObject // id: %4
122-
// CHECK-NEXT: Non Consuming User: %7 = apply %6(%3) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
123-
// CHECK-NEXT: Block: bb0
122+
// CHECK-NEXT: Non Consuming User: end_borrow %3 : $*Builtin.NativeObject
124123
sil [ossa] @store_borrow_result_used_outside_of_borrow_lifetime : $@convention(thin) (@owned Builtin.NativeObject) -> () {
125124
bb0(%0 : @owned $Builtin.NativeObject):
126125
%0a = begin_borrow %0 : $Builtin.NativeObject
@@ -130,6 +129,7 @@ bb0(%0 : @owned $Builtin.NativeObject):
130129
destroy_value %0 : $Builtin.NativeObject
131130
%func = function_ref @use_builtinnativeobject_inguaranteed : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
132131
apply %func(%result) : $@convention(thin) (@in_guaranteed Builtin.NativeObject) -> ()
132+
end_borrow %result : $*Builtin.NativeObject
133133
dealloc_stack %1 : $*Builtin.NativeObject
134134
%9999 = tuple()
135135
return %9999 : $()

‎test/SIL/OwnershipVerifier/use_verifier.sil

+2-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ bb0(%0 : @guaranteed $Builtin.NativeObject):
127127
sil [ossa] @store_borrow_result : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
128128
bb0(%0 : @guaranteed $Builtin.NativeObject):
129129
%1 = alloc_stack $Builtin.NativeObject
130-
store_borrow %0 to %1 : $*Builtin.NativeObject
130+
%sb = store_borrow %0 to %1 : $*Builtin.NativeObject
131+
end_borrow %sb : $*Builtin.NativeObject
131132
dealloc_stack %1 : $*Builtin.NativeObject
132133
%9999 = tuple()
133134
return %9999 : $()

‎test/SIL/Parser/borrow.sil

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ import Builtin
1010
// CHECK: [[BORROWED_ARG2:%.*]] = begin_borrow [[ARG2]]
1111
// CHECK: end_borrow [[BORROWED_ARG2]]
1212
// CHECK: [[MEM:%.*]] = alloc_stack $Builtin.NativeObject
13-
// CHECK: store_borrow [[ARG2]] to [[MEM]] : $*Builtin.NativeObject
14-
// CHECK: end_borrow [[MEM]] : $*Builtin.NativeObject
13+
// CHECK: [[SB:%.*]] = store_borrow [[ARG2]] to [[MEM]] : $*Builtin.NativeObject
14+
// CHECK: end_borrow [[SB]] : $*Builtin.NativeObject
1515
// CHECK: } // end sil function 'borrow_test'
1616
sil [ossa] @borrow_test : $@convention(thin) (@in Builtin.NativeObject, @guaranteed Builtin.NativeObject) -> () {
1717
bb0(%0 : $*Builtin.NativeObject, %1 : @guaranteed $Builtin.NativeObject):
1818
%2 = begin_borrow %1 : $Builtin.NativeObject
1919
end_borrow %2 : $Builtin.NativeObject
2020

2121
%3 = alloc_stack $Builtin.NativeObject
22-
store_borrow %1 to %3 : $*Builtin.NativeObject
23-
end_borrow %3 : $*Builtin.NativeObject
22+
%sb = store_borrow %1 to %3 : $*Builtin.NativeObject
23+
end_borrow %sb : $*Builtin.NativeObject
2424
dealloc_stack %3 : $*Builtin.NativeObject
2525
destroy_addr %0 : $*Builtin.NativeObject
2626

‎test/SIL/Serialization/borrow.sil

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ bb0(%0 : $*Builtin.NativeObject, %1 : @guaranteed $Builtin.NativeObject):
5656
end_borrow %2 : $Builtin.NativeObject
5757

5858
%3 = alloc_stack $Builtin.NativeObject
59-
store_borrow %1 to %3 : $*Builtin.NativeObject
60-
end_borrow %3 : $*Builtin.NativeObject
59+
%sb = store_borrow %1 to %3 : $*Builtin.NativeObject
60+
end_borrow %sb : $*Builtin.NativeObject
6161
dealloc_stack %3 : $*Builtin.NativeObject
6262
destroy_addr %0 : $*Builtin.NativeObject
6363
%4 = tuple()

‎test/SIL/memory_lifetime.sil

+2-1
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,8 @@ bb0(%0 : $*T):
506506
sil [ossa] @test_store_borrow : $@convention(thin) (@guaranteed T) -> () {
507507
bb0(%0 : @guaranteed $T):
508508
%s = alloc_stack $T
509-
store_borrow %0 to %s : $*T
509+
%sb = store_borrow %0 to %s : $*T
510+
end_borrow %sb : $*T
510511
dealloc_stack %s : $*T
511512
%res = tuple ()
512513
return %res : $()

‎test/SIL/memory_lifetime_failures.sil

+23-13
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,12 @@ bb0(%0 : $*T):
271271
return %res : $()
272272
}
273273

274-
// CHECK: SIL memory lifetime failure in @test_store_borrow_destroy: memory is not initialized, but should be
274+
// CHECK: SIL memory lifetime failure in @test_store_borrow_destroy: store-borrow location cannot be written
275275
sil [ossa] @test_store_borrow_destroy : $@convention(thin) (@guaranteed T) -> () {
276276
bb0(%0 : @guaranteed $T):
277277
%s = alloc_stack $T
278-
store_borrow %0 to %s : $*T
278+
%sb = store_borrow %0 to %s : $*T
279+
end_borrow %sb : $*T
279280
destroy_addr %s : $*T
280281
dealloc_stack %s : $*T
281282
%res = tuple ()
@@ -284,13 +285,14 @@ bb0(%0 : @guaranteed $T):
284285

285286
sil [ossa] @func_with_inout_param : $@convention(thin) (@inout T) -> ()
286287

287-
// CHECK: SIL memory lifetime failure in @test_store_borrow_inout: store-borrow location cannot be written
288+
// T-CHECK: SIL memory lifetime failure in @test_store_borrow_inout: store-borrow location cannot be written
288289
sil [ossa] @test_store_borrow_inout : $@convention(thin) (@guaranteed T) -> () {
289290
bb0(%0 : @guaranteed $T):
290291
%s = alloc_stack $T
291-
store_borrow %0 to %s : $*T
292+
%sb = store_borrow %0 to %s : $*T
292293
%f = function_ref @func_with_inout_param : $@convention(thin) (@inout T) -> ()
293-
%a = apply %f(%s) : $@convention(thin) (@inout T) -> ()
294+
%a = apply %f(%sb) : $@convention(thin) (@inout T) -> ()
295+
end_borrow %sb : $*T
294296
dealloc_stack %s : $*T
295297
%res = tuple ()
296298
return %res : $()
@@ -300,7 +302,8 @@ bb0(%0 : @guaranteed $T):
300302
sil [ossa] @test_store_borrow_store : $@convention(thin) (@guaranteed T, @owned T) -> () {
301303
bb0(%0 : @guaranteed $T, %1 : @owned $T):
302304
%s = alloc_stack $T
303-
store_borrow %0 to %s : $*T
305+
%sb = store_borrow %0 to %s : $*T
306+
end_borrow %sb : $*T
304307
store %1 to [assign] %s : $*T
305308
dealloc_stack %s : $*T
306309
%res = tuple ()
@@ -311,7 +314,8 @@ bb0(%0 : @guaranteed $T, %1 : @owned $T):
311314
sil [ossa] @test_store_borrow_load : $@convention(thin) (@guaranteed T) -> @owned T {
312315
bb0(%0 : @guaranteed $T):
313316
%s = alloc_stack $T
314-
store_borrow %0 to %s : $*T
317+
%sb = store_borrow %0 to %s : $*T
318+
end_borrow %sb : $*T
315319
%res = load [take] %s : $*T
316320
dealloc_stack %s : $*T
317321
return %res : $T
@@ -321,7 +325,8 @@ bb0(%0 : @guaranteed $T):
321325
sil [ossa] @test_store_borrow_copy_src : $@convention(thin) (@guaranteed T) -> @out T {
322326
bb0(%0 : $*T, %1 : @guaranteed $T):
323327
%s = alloc_stack $T
324-
store_borrow %1 to %s : $*T
328+
%sb = store_borrow %1 to %s : $*T
329+
end_borrow %sb : $*T
325330
copy_addr [take] %s to [initialization] %0 : $*T
326331
dealloc_stack %s : $*T
327332
%res = tuple ()
@@ -332,7 +337,8 @@ bb0(%0 : $*T, %1 : @guaranteed $T):
332337
sil [ossa] @test_store_borrow_copy_dst : $@convention(thin) (@in_guaranteed T, @guaranteed T) -> () {
333338
bb0(%0 : $*T, %1 : @guaranteed $T):
334339
%s = alloc_stack $T
335-
store_borrow %1 to %s : $*T
340+
%sb = store_borrow %1 to %s : $*T
341+
end_borrow %sb : $*T
336342
copy_addr %0 to %s : $*T
337343
dealloc_stack %s : $*T
338344
%res = tuple ()
@@ -343,7 +349,8 @@ bb0(%0 : $*T, %1 : @guaranteed $T):
343349
sil [ossa] @test_store_borrow_init_enum : $@convention(thin) (@guaranteed Optional<T>) -> () {
344350
bb0(%0 : @guaranteed $Optional<T>):
345351
%s = alloc_stack $Optional<T>
346-
store_borrow %0 to %s : $*Optional<T>
352+
%sb = store_borrow %0 to %s : $*Optional<T>
353+
end_borrow %sb : $*Optional<T>
347354
%ie = init_enum_data_addr %s : $*Optional<T>, #Optional.some!enumelt
348355
dealloc_stack %s : $*Optional<T>
349356
%res = tuple ()
@@ -354,8 +361,9 @@ bb0(%0 : @guaranteed $Optional<T>):
354361
sil [ossa] @test_store_borrow_take_enum : $@convention(thin) (@guaranteed Optional<T>) -> () {
355362
bb0(%0 : @guaranteed $Optional<T>):
356363
%s = alloc_stack $Optional<T>
357-
store_borrow %0 to %s : $*Optional<T>
364+
%sb = store_borrow %0 to %s : $*Optional<T>
358365
%ue = unchecked_take_enum_data_addr %s : $*Optional<T>, #Optional.some!enumelt
366+
end_borrow %sb : $*Optional<T>
359367
dealloc_stack %s : $*Optional<T>
360368
%res = tuple ()
361369
return %res : $()
@@ -369,7 +377,8 @@ bb0(%0 : @guaranteed $T):
369377
store %copy to [init] %stk : $*T
370378
%ld = load [take] %stk : $*T
371379
destroy_value %ld : $T
372-
store_borrow %0 to %stk : $*T
380+
%sb = store_borrow %0 to %stk : $*T
381+
end_borrow %sb : $*T
373382
dealloc_stack %stk : $*T
374383
%8 = tuple ()
375384
return %8 : $()
@@ -385,7 +394,8 @@ bb0(%0 : @guaranteed $T):
385394
destroy_value %ld : $T
386395
br bb1
387396
bb1:
388-
store_borrow %0 to %stk : $*T
397+
%sb = store_borrow %0 to %stk : $*T
398+
end_borrow %sb : $*T
389399
dealloc_stack %stk : $*T
390400
%8 = tuple ()
391401
return %8 : $()

0 commit comments

Comments
 (0)
Please sign in to comment.