sil: load [copy] affects reference counting

Based on what I see from OwnershipModelEliminator,
`%x = load [copy] %y` can turn into a plain load
followed by a retain of the loaded value.

See `NonTrivialLoadableTypeLowering::emitLoad`
This commit is contained in:
Kavon Farvardin
2025-09-16 14:33:43 -07:00
parent cfe9f90347
commit 2dea3ca3fc
2 changed files with 11 additions and 4 deletions

View File

@@ -832,7 +832,7 @@ load-ownership-kind ::= 'take'
```
Loads the value at address `%0` from memory. `T` must be a loadable
type. This does not affect the reference count, if any, of the loaded
type. An unqualified load does not affect the reference count, if any, of the loaded
value; the value must be retained explicitly if necessary. It is
undefined behavior to load from uninitialized memory or to load from an
address that points to deallocated storage.
@@ -840,8 +840,8 @@ address that points to deallocated storage.
In OSSA the ownership kind specifies how to handle ownership:
- **trivial**: the loaded value is trivial and no further action must be taken
than to load the raw bits of the value
- **copy**: the loaded value is copied and the original value stays in the
memory location.
- **copy**: the loaded value is copied (e.g., retained) and the original value
stays in the memory location.
- **take**: the value is _moved_ from the memory location without copying.
After the `load`, the memory location remains uninitialized.

View File

@@ -552,7 +552,6 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType)
case SILInstructionKind::CopyableToMoveOnlyWrapperValueInst:
case SILInstructionKind::MoveOnlyWrapperToCopyableValueInst:
case SILInstructionKind::UncheckedOwnershipConversionInst:
case SILInstructionKind::LoadInst:
case SILInstructionKind::LoadBorrowInst:
case SILInstructionKind::BeginBorrowInst:
case SILInstructionKind::BorrowedFromInst:
@@ -626,6 +625,14 @@ RuntimeEffect swift::getRuntimeEffect(SILInstruction *inst, SILType &impactType)
case SILInstructionKind::TypeValueInst:
case SILInstructionKind::IgnoredUseInst:
return RuntimeEffect::NoEffect;
case SILInstructionKind::LoadInst: {
if (cast<LoadInst>(inst)->getOwnershipQualifier() == LoadOwnershipQualifier::Copy) {
return ifNonTrivial(inst->getOperand(0)->getType(),
RuntimeEffect::RefCounting);
}
return RuntimeEffect::NoEffect;
}
case SILInstructionKind::OpenExistentialMetatypeInst:
case SILInstructionKind::OpenExistentialBoxInst: