@@ -347,6 +347,27 @@ static bool isStoreCopy(SILValue value) {
347
347
if (!copyInst->hasOneUse ())
348
348
return false ;
349
349
350
+ auto *user = value->getSingleUse ()->getUser ();
351
+ auto *storeInst = dyn_cast<StoreInst>(user);
352
+ if (!storeInst)
353
+ return false ;
354
+
355
+ SSAPrunedLiveness liveness;
356
+ auto isStoreOutOfRange = [&liveness, storeInst](SILValue root) {
357
+ liveness.initializeDef (root);
358
+ auto summary = liveness.computeSimple ();
359
+ if (summary.addressUseKind != AddressUseKind::NonEscaping) {
360
+ return true ;
361
+ }
362
+ if (summary.innerBorrowKind != InnerBorrowKind::Contained) {
363
+ return true ;
364
+ }
365
+ if (!liveness.isWithinBoundary (storeInst)) {
366
+ return true ;
367
+ }
368
+ return false ;
369
+ };
370
+
350
371
auto source = copyInst->getOperand ();
351
372
if (source->getOwnershipKind () == OwnershipKind::Guaranteed) {
352
373
// [in_guaranteed_begin_apply_results] If any root of the source is a
@@ -356,19 +377,30 @@ static bool isStoreCopy(SILValue value) {
356
377
SmallVector<SILValue, 4 > roots;
357
378
findGuaranteedReferenceRoots (source, /* lookThroughNestedBorrows=*/ true ,
358
379
roots);
359
- if (llvm::any_of (roots, [](SILValue root) {
360
- // Handle forwarding phis conservatively rather than recursing.
361
- if (SILArgument::asPhi (root) && !BorrowedValue (root))
362
- return true ;
363
-
364
- return isa<BeginApplyInst>(root->getDefiningInstruction ());
365
- })) {
380
+ // TODO: Rather than checking whether the store is out of range of any
381
+ // guaranteed root's SSAPrunedLiveness, instead check whether it is out of
382
+ // range of ExtendedLiveness of the borrow introducers:
383
+ // - visit borrow introducers via visitBorrowIntroducers
384
+ // - call ExtendedLiveness.compute on each borrow introducer
385
+ if (llvm::any_of (roots, [&](SILValue root) {
386
+ // Handle forwarding phis conservatively rather than recursing.
387
+ if (SILArgument::asPhi (root) && !BorrowedValue (root))
388
+ return true ;
389
+
390
+ if (isa<BeginApplyInst>(root->getDefiningInstruction ())) {
391
+ return true ;
392
+ }
393
+ return isStoreOutOfRange (root);
394
+ })) {
395
+ return false ;
396
+ }
397
+ } else if (source->getOwnershipKind () == OwnershipKind::Owned) {
398
+ if (isStoreOutOfRange (source)) {
366
399
return false ;
367
400
}
368
401
}
369
402
370
- auto *user = value->getSingleUse ()->getUser ();
371
- return isa<StoreInst>(user);
403
+ return true ;
372
404
}
373
405
374
406
void ValueStorageMap::insertValue (SILValue value, SILValue storageAddress) {
@@ -2280,9 +2312,9 @@ void ApplyRewriter::convertBeginApplyWithOpaqueYield() {
2280
2312
info.isConsumed () ? IsTake : IsNotTake,
2281
2313
IsInitialization);
2282
2314
} else {
2283
- // [in_guaranteed_begin_apply_results] Because OSSA ensure that all uses
2284
- // of a guaranteed value produced by a begin_apply are used within the
2285
- // coroutine's range, AddressLowering will not introduce uses of
2315
+ // [in_guaranteed_begin_apply_results] Because OSSA ensures that all
2316
+ // uses of a guaranteed value produced by a begin_apply are used within
2317
+ // the coroutine's range, AddressLowering will not introduce uses of
2286
2318
// invalid memory by rewriting the uses of a yielded guaranteed opaque
2287
2319
// value as uses of yielded guaranteed storage. However, it must
2288
2320
// allocate storage for copies of [projections of] such values.
@@ -2994,12 +3026,12 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
2994
3026
switch (bi->getBuiltinKind ().value_or (BuiltinValueKind::None)) {
2995
3027
case BuiltinValueKind::ResumeNonThrowingContinuationReturning: {
2996
3028
SILValue opAddr = addrMat.materializeAddress (use->get ());
2997
- bi->setOperand (1 , opAddr);
3029
+ bi->setOperand (use-> getOperandNumber () , opAddr);
2998
3030
break ;
2999
3031
}
3000
3032
case BuiltinValueKind::ResumeThrowingContinuationReturning: {
3001
3033
SILValue opAddr = addrMat.materializeAddress (use->get ());
3002
- bi->setOperand (1 , opAddr);
3034
+ bi->setOperand (use-> getOperandNumber () , opAddr);
3003
3035
break ;
3004
3036
}
3005
3037
case BuiltinValueKind::Copy: {
@@ -3768,7 +3800,7 @@ static void rewriteFunction(AddressLoweringState &pass) {
3768
3800
originalUses.insert (oper);
3769
3801
UseRewriter::rewriteUse (oper, pass);
3770
3802
}
3771
- // Rewrite every new uses that was added.
3803
+ // Rewrite every new use that was added.
3772
3804
uses.clear ();
3773
3805
for (auto *use : valueDef->getUses ()) {
3774
3806
if (originalUses.contains (use))
0 commit comments