@@ -1190,7 +1190,7 @@ void Implementation::rewriteUses(InstructionDeleter *deleter) {
1190
1190
LLVM_DEBUG (llvm::dbgs () << " Computed available values for block bb"
1191
1191
<< block->getDebugID () << ' \n ' ;
1192
1192
availableValues.print (llvm::dbgs (), " " ));
1193
- // Then walk from the top to the bottom of the block rewriting as we go.
1193
+ // Then walk from the beginning to the end of the block, rewriting as we go.
1194
1194
for (auto ii = block->begin (), ie = block->end (); ii != ie;) {
1195
1195
auto *inst = &*ii;
1196
1196
++ii;
@@ -1336,13 +1336,6 @@ void Implementation::rewriteUses(InstructionDeleter *deleter) {
1336
1336
borrowBuilder.createGuaranteedMoveOnlyWrapperToCopyableValue (
1337
1337
loc, value);
1338
1338
}
1339
- // NOTE: oldInst may be nullptr if our operand is a SILArgument
1340
- // which can happen with switch_enum.
1341
- auto *oldInst = operand.get ()->getDefiningInstruction ();
1342
- operand.set (value);
1343
- if (oldInst && deleter)
1344
- deleter->forceTrackAsDead (oldInst);
1345
-
1346
1339
// If we have a terminator that is a trivial use (e.x.: we
1347
1340
// struct_extract a trivial value). Just put the end_borrow before the
1348
1341
// terminator.
@@ -1351,19 +1344,31 @@ void Implementation::rewriteUses(InstructionDeleter *deleter) {
1351
1344
operand.getOperandOwnership () == OperandOwnership::TrivialUse) {
1352
1345
SILBuilderWithScope endBuilder (inst);
1353
1346
endBuilder.createEndBorrow (getSafeLoc (inst), borrow);
1354
- continue ;
1347
+ goto update_operand ;
1355
1348
} else {
1356
1349
// Otherwise, put the end_borrow.
1357
1350
for (auto *succBlock : ti->getSuccessorBlocks ()) {
1358
1351
auto *nextInst = &succBlock->front ();
1359
1352
SILBuilderWithScope endBuilder (nextInst);
1360
1353
endBuilder.createEndBorrow (getSafeLoc (nextInst), borrow);
1361
1354
}
1362
- continue ;
1355
+ goto update_operand ;
1363
1356
}
1364
1357
}
1365
1358
1366
1359
insertEndBorrowsForNonConsumingUse (&operand, borrow);
1360
+ update_operand:
1361
+ // We update the operand after placing end_borrows, since we might
1362
+ // need the original operand's lifetime to correctly delineate the
1363
+ // new lifetime, such as if there is an InteriorPointerOperand.
1364
+
1365
+ // NOTE: oldInst may be nullptr if our operand is a SILArgument
1366
+ // which can happen with switch_enum.
1367
+ auto *oldInst = operand.get ()->getDefiningInstruction ();
1368
+ operand.set (value);
1369
+ if (oldInst && deleter)
1370
+ deleter->forceTrackAsDead (oldInst);
1371
+
1367
1372
continue ;
1368
1373
}
1369
1374
0 commit comments