Skip to content

Commit 43b61ab

Browse files
committed
Fix BorrowingOperand::visitScopeEndingUses() invariants.
This API only makes sense for a scoped borrow-introducer such as: - reborrow - owned mark_dependence Borrowing operands that forward guaranteed values do not have scope-ending uses.
1 parent 0989618 commit 43b61ab

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

include/swift/SIL/SILInstruction.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8815,10 +8815,14 @@ class MarkDependenceInst
88158815
uint8_t(MarkDependenceKind::Escaping);
88168816
}
88178817

8818-
/// Visit the instructions that end the lifetime of an OSSA on-stack closure.
8818+
/// Visit the instructions that end the lifetime the dependent value.
8819+
///
8820+
/// Preconditions:
8821+
/// - isNonEscaping()
8822+
/// - Produces an owned, Escapable, non-address value
88198823
bool visitNonEscapingLifetimeEnds(
88208824
llvm::function_ref<bool (Operand*)> visitScopeEnd,
8821-
llvm::function_ref<bool (Operand*)> visitUnknownUse) const;
8825+
llvm::function_ref<bool (Operand*)> visitUnknownUse);
88228826
};
88238827

88248828
/// Promote an Objective-C block that is on the stack to the heap, or simply

lib/SIL/IR/SILInstruction.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2022,10 +2022,13 @@ visitRecursivelyLifetimeEndingUses(
20222022
// the dependent value.
20232023
bool MarkDependenceInst::visitNonEscapingLifetimeEnds(
20242024
llvm::function_ref<bool (Operand *)> visitScopeEnd,
2025-
llvm::function_ref<bool (Operand *)> visitUnknownUse) const {
2025+
llvm::function_ref<bool (Operand *)> visitUnknownUse) {
20262026
assert(getFunction()->hasOwnership() && isNonEscaping()
20272027
&& "only meaningful for nonescaping dependencies");
20282028
assert(getType().isObject() && "lifetime ends only exist for values");
2029+
assert(getOwnershipKind() == OwnershipKind::Owned
2030+
&& getType().isEscapable(*getFunction())
2031+
&& "only correct for owned escapable values");
20292032
bool noUsers = true;
20302033
if (!visitRecursivelyLifetimeEndingUses(this, noUsers, visitScopeEnd,
20312034
visitUnknownUse)) {

lib/SIL/Utils/OwnershipUtils.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,12 @@ bool BorrowingOperand::visitScopeEndingUses(
662662
switch (kind) {
663663
case BorrowingOperandKind::Invalid:
664664
llvm_unreachable("Using invalid case");
665-
case BorrowingOperandKind::BeginBorrow:
666-
case BorrowingOperandKind::BorrowedFrom: {
665+
case BorrowingOperandKind::BorrowedFrom:
666+
if (!cast<BorrowedFromInst>(op->getUser())->isReborrow()) {
667+
return visitUnknownUse(op);
668+
}
669+
LLVM_FALLTHROUGH;
670+
case BorrowingOperandKind::BeginBorrow: {
667671
bool deadBorrow = true;
668672
for (auto *use : cast<SingleValueInstruction>(op->getUser())->getUses()) {
669673
if (use->isLifetimeEnding()) {
@@ -713,10 +717,16 @@ bool BorrowingOperand::visitScopeEndingUses(
713717
return user->visitOnStackLifetimeEnds(visitScopeEnd);
714718
}
715719
case BorrowingOperandKind::MarkDependenceNonEscaping: {
716-
auto *user = cast<MarkDependenceInst>(op->getUser());
717-
assert(user->isNonEscaping() && "escaping dependencies don't borrow");
718-
assert(user->getType().isObject() && "borrows only exist for values");
719-
return user->visitNonEscapingLifetimeEnds(visitScopeEnd, visitUnknownUse);
720+
auto *mdi = cast<MarkDependenceInst>(op->getUser());
721+
assert(mdi->isNonEscaping() && "escaping dependencies don't borrow");
722+
// MarkDependenceInst::visitNonEscapingLifetimeEnds only makes sense for
723+
// owned, escapable, non-address values.
724+
if (mdi->getOwnershipKind() == OwnershipKind::Owned
725+
&& mdi->getType().isObject()
726+
&& mdi->getType().isEscapable(*mdi->getFunction())) {
727+
return mdi->visitNonEscapingLifetimeEnds(visitScopeEnd, visitUnknownUse);
728+
}
729+
return visitUnknownUse(op);
720730
}
721731
case BorrowingOperandKind::BeginAsyncLet: {
722732
auto user = cast<BuiltinInst>(op->getUser());

0 commit comments

Comments
 (0)