[SIL] Fix visitAccessedAddress @ end_borrow

`end_borrow` instructions may end the scopes introduced by `load_borrow`
or `store_borrow` instructions, or those introduced by `begin_borrow`
whose operand's guaranteed root includes a `load_borrow`.

Previously, such scope ending instructions which end the scope
associated with a borrowing load or store were not regarded as accessing
the loaded-from or stored-to address.  One consequence of this is that
they were not regarded as accessing pointers and thus not as deinit
barriers; that in turn resulted in `destroy_addr`s being hoisted into
such borrow scopes.

Here this is fixed by regarding such `end_borrow`s to access the
loaded-from or stored-to address of the scope-introducing `load_borrow`
or `store_borrow` respectively.

rdar://157772187
This commit is contained in:
Nate Chandler
2025-08-11 08:13:44 -07:00
parent 573607ff36
commit 66a9b77835
2 changed files with 41 additions and 1 deletions

View File

@@ -2796,6 +2796,23 @@ void swift::visitAccessedAddress(SILInstruction *I,
visitor(singleOperand);
return;
}
case SILInstructionKind::EndBorrowInst: {
auto *ebi = cast<EndBorrowInst>(I);
SmallVector<SILValue, 4> roots;
findGuaranteedReferenceRoots(ebi->getOperand(),
/*lookThroughNestedBorrows=*/true, roots);
for (auto root : roots) {
if (auto *lbi = dyn_cast<LoadBorrowInst>(root)) {
visitor(&lbi->getOperandRef());
return;
}
if (auto *sbi = dyn_cast<StoreBorrowInst>(root)) {
visitor(&sbi->getOperandRef(StoreInst::Dest));
return;
}
}
break;
}
// Non-access cases: these are marked with memory side effects, but, by
// themselves, do not access formal memory.
#define UNCHECKED_REF_STORAGE(Name, ...) \
@@ -2828,7 +2845,6 @@ void swift::visitAccessedAddress(SILInstruction *I,
case SILInstructionKind::DropDeinitInst:
case SILInstructionKind::EndAccessInst:
case SILInstructionKind::EndApplyInst:
case SILInstructionKind::EndBorrowInst:
case SILInstructionKind::EndUnpairedAccessInst:
case SILInstructionKind::EndLifetimeInst:
case SILInstructionKind::ExistentialMetatypeInst: