Skip to content

Commit 950bcd1

Browse files
authored
Merge pull request swiftlang#35834 from atrick/fix-copyprop-reborrow2
Fix copy-propagation: bail-out on reborrows.
2 parents bcb25d3 + 82c79b7 commit 950bcd1

File tree

2 files changed

+63
-13
lines changed

2 files changed

+63
-13
lines changed

lib/SILOptimizer/Utils/CanonicalOSSALifetime.cpp

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -408,13 +408,22 @@ bool CanonicalizeOSSALifetime::computeCanonicalLiveness() {
408408
recordConsumingUse(use);
409409
break;
410410
case OperandOwnership::Borrow:
411-
// The liveness of an entire extended borrow scope is modeled as use
412-
// points and the scope-ending uses.
413-
BorrowingOperand(use).visitExtendedScopeEndingUses(
414-
[this](Operand *end) {
415-
liveness.updateForUse(end->getUser(), /*lifetimeEnding*/ false);
416-
return true;
417-
});
411+
// A nested borrow scope is considered a use-point at each scope ending
412+
// instruction.
413+
//
414+
// TODO: Handle reborrowed copies by considering the extended borrow
415+
// scope. Temporarily bail-out on reborrows because we can't handle uses
416+
// that aren't dominated by currentDef.
417+
if (!BorrowingOperand(use).visitScopeEndingUses(
418+
[this](Operand *end) {
419+
if (end->getOperandOwnership() == OperandOwnership::Reborrow) {
420+
return false;
421+
}
422+
liveness.updateForUse(end->getUser(), /*lifetimeEnding*/ false);
423+
return true;
424+
})) {
425+
return false;
426+
}
418427
break;
419428
case OperandOwnership::InteriorPointer:
420429
case OperandOwnership::ForwardingBorrow:

test/SILOptimizer/copy_propagation.sil

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ sil_stage canonical
99
import Builtin
1010
import Swift
1111

12+
sil [ossa] @getOwnedC : $@convention(thin) () -> (@owned C)
1213
sil [ossa] @takeOwned : $@convention(thin) <T> (@in T) -> ()
1314
sil [ossa] @takeMultipleOwned : $@convention(thin) <T> (@in T, @in T) -> ()
1415
sil [ossa] @takeGuaranteed : $@convention(thin) <T> (@in_guaranteed T) -> ()
@@ -1458,17 +1459,18 @@ bb3:
14581459
// with cross-block reborrows. Its lifetime must be extended past the
14591460
// end_borrow of the phi.
14601461
//
1462+
// TODO: CanonicalizeOSSA currently bails out on reborrows.
1463+
//
14611464
// CHECK-LABEL: sil [ossa] @testSubReborrowExtension : $@convention(thin) () -> () {
14621465
// CHECK: bb0:
1463-
// CHECK: [[ALLOC:%.*]] = alloc_ref $C
1464-
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $C
1466+
// CHECK: [[ALLOC:%.*]] = alloc_ref $C
1467+
// CHECK: [[CP:%.*]] = copy_value %0 : $C
1468+
// CHECK: [[BORROW:%.*]] = begin_borrow %0 : $C
14651469
// CHECK: cond_br undef, bb1, bb2
14661470
// CHECK: bb1:
1467-
// CHECK: [[CP1:%.*]] = copy_value %0 : $C
1468-
// CHECK: br bb3([[CP1]] : $C, [[BORROW]] : $C)
1471+
// CHECK: br bb3([[CP]] : $C, [[BORROW]] : $C)
14691472
// CHECK: bb2:
1470-
// CHECK: [[CP2:%.*]] = copy_value %0 : $C
1471-
// CHECK: br bb3([[CP2]] : $C, [[BORROW]] : $C)
1473+
// CHECK: br bb3([[CP]] : $C, [[BORROW]] : $C)
14721474
// CHECK: bb3([[OWNEDPHI:%.*]] : @owned $C, [[BORROWPHI:%.*]] @guaranteed $C
14731475
// CHECK: end_borrow [[BORROWPHI]]
14741476
// CHECK: destroy_value [[OWNEDPHI]] : $C
@@ -1628,3 +1630,42 @@ bb3(%borrowphi : @guaranteed $C):
16281630
%99 = tuple ()
16291631
return %99 : $()
16301632
}
1633+
1634+
// Test a reborrow of an owned-and-copied def that does not dominate
1635+
// the extended borrow scope.
1636+
//
1637+
// CHECK-LABEL: sil [ossa] @testOwnedReborrow : $@convention(thin) (@owned C) -> () {
1638+
// CHECK: bb1:
1639+
// CHECK: destroy_value %0 : $C
1640+
// CHECK: [[CALL:%.*]] = apply %{{.*}}() : $@convention(thin) () -> @owned C
1641+
// CHECK: [[COPY1:%.*]] = copy_value [[CALL]] : $C
1642+
// CHECK: begin_borrow [[COPY1]] : $C
1643+
// CHECK: destroy_value [[CALL]] : $C
1644+
// CHECK: br bb3(%{{.*}} : $C, [[COPY1]] : $C)
1645+
// CHECK: bb2:
1646+
// CHECK: begin_borrow %0 : $C
1647+
// CHECK: br bb3(%{{.*}} : $C, %0 : $C)
1648+
// CHECK: bb3(%{{.*}} : @guaranteed $C, [[COPYPHI:%.*]] : @owned $C):
1649+
// CHECK: end_borrow
1650+
// CHECK: destroy_value [[COPYPHI]] : $C
1651+
// CHECK-LABEL: } // end sil function 'testOwnedReborrow'
1652+
sil [ossa] @testOwnedReborrow : $@convention(thin) (@owned C) -> () {
1653+
bb0(%0 : @owned $C):
1654+
cond_br undef, bb1, bb2
1655+
bb1:
1656+
destroy_value %0 : $C
1657+
%f = function_ref @getOwnedC : $@convention(thin) () -> (@owned C)
1658+
%owned1 = apply %f() : $@convention(thin) () -> (@owned C)
1659+
%copy1 = copy_value %owned1 : $C
1660+
%borrow1 = begin_borrow %copy1 : $C
1661+
destroy_value %owned1 : $C
1662+
br bb3(%borrow1 : $C, %copy1 : $C)
1663+
bb2:
1664+
%borrow2 = begin_borrow %0 : $C
1665+
br bb3(%borrow2 : $C, %0 : $C)
1666+
bb3(%borrow3 : @guaranteed $C, %copy3 : @owned $C):
1667+
end_borrow %borrow3 : $C
1668+
destroy_value %copy3 : $C
1669+
%result = tuple ()
1670+
return %result : $()
1671+
}

0 commit comments

Comments
 (0)