mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
ConditionForwarding: don't violate ownership
Instructions in a block, which is moved, must not use any (non-trivial) value because we don't do liveness analysis. When moving a block, there is no guarantee that the operand value is still alive at the new location. Fixes an ownership violation error rdar://146630743
This commit is contained in:
@@ -126,8 +126,25 @@ private:
|
||||
|
||||
/// Returns true if all instructions of block \p BB are safe to be moved
|
||||
/// across other code.
|
||||
static bool hasNoRelevantSideEffects(SILBasicBlock *BB) {
|
||||
static bool hasNoRelevantSideEffects(SILBasicBlock *BB, EnumInst *enumInst) {
|
||||
for (SILInstruction &I : *BB) {
|
||||
if (BB->getParent()->hasOwnership() && &I != enumInst) {
|
||||
// The instruction must not use any (non-trivial) value because we don't
|
||||
// do liveness analysis. When moving the block, there is no guarantee that
|
||||
// the operand value is still alive at the new location.
|
||||
for (Operand *op : I.getRealOperands()) {
|
||||
SILValue opv = op->get();
|
||||
// The `enum` is an exception, because it's a forwarded value and we already
|
||||
// check that it's forwarded to the `switch_enum` at the new location.
|
||||
if (opv == enumInst)
|
||||
continue;
|
||||
// If the value is defined in the block it's a block-local liferange.
|
||||
if (opv->getParentBlock() == BB)
|
||||
continue;
|
||||
if (opv->getOwnershipKind() != OwnershipKind::None)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (I.getMemoryBehavior() == MemoryBehavior::None)
|
||||
continue;
|
||||
if (auto *CF = dyn_cast<CondFailInst>(&I)) {
|
||||
@@ -144,9 +161,6 @@ static bool hasNoRelevantSideEffects(SILBasicBlock *BB) {
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
if (isa<BeginBorrowInst>(&I) || isa<EndBorrowInst>(&I)) {
|
||||
continue;
|
||||
}
|
||||
LLVM_DEBUG(llvm::dbgs() << "Bailing out, found inst with side-effects ");
|
||||
LLVM_DEBUG(I.dump());
|
||||
return false;
|
||||
@@ -212,7 +226,7 @@ bool ConditionForwarding::tryOptimize(SwitchEnumInst *SEI) {
|
||||
CommonBranchBlock = PredPred;
|
||||
|
||||
// We cannot move the block across other code if it has side-effects.
|
||||
if (!hasNoRelevantSideEffects(Pred))
|
||||
if (!hasNoRelevantSideEffects(Pred, EI))
|
||||
return false;
|
||||
PredBlocks.push_back(Pred);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user