Skip to content

Commit 554f967

Browse files
Merge pull request swiftlang#65566 from nate-chandler/rdar108745323/2
[SemanticARCOpts] Check uses in moved load range.
2 parents 6d01f25 + 2163269 commit 554f967

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed

lib/SILOptimizer/SemanticARC/LoadCopyToLoadBorrowOpt.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,15 @@ class StorageGuaranteesLoadVisitor
140140
SmallVector<BeginAccessInst *, 16> foundBeginAccess;
141141
LinearLifetimeChecker checker(&ctx.getDeadEndBlocks());
142142
SILValue introducerValue = liveRange.getIntroducer().value;
143-
if (!checker.usesNotContainedWithinLifetime(introducerValue,
144-
liveRange.getDestroyingUses(),
145-
*wellBehavedWrites)) {
143+
SmallVector<Operand *, 4> consumingUses;
144+
for (auto *op : liveRange.getDestroyingUses()) {
145+
consumingUses.push_back(op);
146+
}
147+
for (auto *op : liveRange.getUnknownConsumingUses()) {
148+
consumingUses.push_back(op);
149+
}
150+
if (!checker.usesNotContainedWithinLifetime(
151+
introducerValue, consumingUses, *wellBehavedWrites)) {
146152
return answer(true);
147153
}
148154

@@ -368,7 +374,8 @@ bool SemanticARCOptVisitor::performLoadCopyToLoadBorrowOptimization(
368374
// Then check if our address is ever written to. If it is, then we cannot use
369375
// the load_borrow because the stored value may be released during the loaded
370376
// value's live range.
371-
if (isWrittenTo(ctx, li, lr))
377+
if (isWrittenTo(ctx, li, lr) ||
378+
(li != original && isWrittenTo(ctx, li, OwnershipLiveRange(li))))
372379
return false;
373380

374381
// Ok, we can perform our optimization. Convert the load [copy] into a

lib/SILOptimizer/SemanticARC/OwnershipLiveRange.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ class LLVM_LIBRARY_VISIBILITY OwnershipLiveRange {
109109

110110
ArrayRef<Operand *> getDestroyingUses() const { return destroyingUses; }
111111

112+
ArrayRef<Operand *> getUnknownConsumingUses() const {
113+
return unknownConsumingUses;
114+
}
115+
112116
private:
113117
struct OperandToUser;
114118

test/SILOptimizer/semantic-arc-opts-loadcopy-to-loadborrow.sil

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,3 +1601,39 @@ bb0:
16011601
%retval = tuple ()
16021602
return %retval : $()
16031603
}
1604+
1605+
// CHECK-LABEL: sil [ossa] @load_take_between_load_copy_and_move_inout : {{.*}} {
1606+
// CHECK: load [copy]
1607+
// CHECK-LABEL: } // end sil function 'load_take_between_load_copy_and_move_inout'
1608+
sil [ossa] @load_take_between_load_copy_and_move_inout : $@convention(thin) (@inout C) -> () {
1609+
entry(%addr : $*C):
1610+
%v1 = load [copy] %addr : $*C
1611+
%v2 = load [take] %addr : $*C
1612+
%m1 = move_value [lexical] %v1 : $C
1613+
destroy_value %m1 : $C
1614+
store %v2 to [init] %addr : $*C
1615+
%retval = tuple ()
1616+
return %retval : $()
1617+
}
1618+
1619+
// CHECK-LABEL: sil [ossa] @load_take_between_load_copy_and_move_stack : {{.*}} {
1620+
// CHECK: load [copy]
1621+
// CHECK-LABEL: } // end sil function 'load_take_between_load_copy_and_move_stack'
1622+
sil [ossa] @load_take_between_load_copy_and_move_stack : $@convention(thin) () -> () {
1623+
entry:
1624+
%addr = alloc_stack $C
1625+
%getC = function_ref @getC : $@convention(thin) () -> (@owned C)
1626+
%stored = apply %getC() : $@convention(thin) () -> (@owned C)
1627+
store %stored to [init] %addr : $*C
1628+
1629+
%v1 = load [copy] %addr : $*C
1630+
%v2 = load [take] %addr : $*C
1631+
%m1 = move_value [lexical] %v1 : $C
1632+
destroy_value %m1 : $C
1633+
store %v2 to [init] %addr : $*C
1634+
1635+
destroy_addr %addr : $*C
1636+
dealloc_stack %addr : $*C
1637+
%retval = tuple ()
1638+
return %retval : $()
1639+
}

0 commit comments

Comments
 (0)