@@ -347,6 +347,27 @@ static bool isStoreCopy(SILValue value) {
347347 if (!copyInst->hasOneUse ())
348348 return false ;
349349
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+
350371 auto source = copyInst->getOperand ();
351372 if (source->getOwnershipKind () == OwnershipKind::Guaranteed) {
352373 // [in_guaranteed_begin_apply_results] If any root of the source is a
@@ -356,19 +377,30 @@ static bool isStoreCopy(SILValue value) {
356377 SmallVector<SILValue, 4 > roots;
357378 findGuaranteedReferenceRoots (source, /* lookThroughNestedBorrows=*/ true ,
358379 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)) {
366399 return false ;
367400 }
368401 }
369402
370- auto *user = value->getSingleUse ()->getUser ();
371- return isa<StoreInst>(user);
403+ return true ;
372404}
373405
374406void ValueStorageMap::insertValue (SILValue value, SILValue storageAddress) {
@@ -2280,9 +2312,9 @@ void ApplyRewriter::convertBeginApplyWithOpaqueYield() {
22802312 info.isConsumed () ? IsTake : IsNotTake,
22812313 IsInitialization);
22822314 } 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
22862318 // invalid memory by rewriting the uses of a yielded guaranteed opaque
22872319 // value as uses of yielded guaranteed storage. However, it must
22882320 // allocate storage for copies of [projections of] such values.
@@ -2994,12 +3026,12 @@ class UseRewriter : SILInstructionVisitor<UseRewriter> {
29943026 switch (bi->getBuiltinKind ().value_or (BuiltinValueKind::None)) {
29953027 case BuiltinValueKind::ResumeNonThrowingContinuationReturning: {
29963028 SILValue opAddr = addrMat.materializeAddress (use->get ());
2997- bi->setOperand (1 , opAddr);
3029+ bi->setOperand (use-> getOperandNumber () , opAddr);
29983030 break ;
29993031 }
30003032 case BuiltinValueKind::ResumeThrowingContinuationReturning: {
30013033 SILValue opAddr = addrMat.materializeAddress (use->get ());
3002- bi->setOperand (1 , opAddr);
3034+ bi->setOperand (use-> getOperandNumber () , opAddr);
30033035 break ;
30043036 }
30053037 case BuiltinValueKind::Copy: {
@@ -3768,7 +3800,7 @@ static void rewriteFunction(AddressLoweringState &pass) {
37683800 originalUses.insert (oper);
37693801 UseRewriter::rewriteUse (oper, pass);
37703802 }
3771- // Rewrite every new uses that was added.
3803+ // Rewrite every new use that was added.
37723804 uses.clear ();
37733805 for (auto *use : valueDef->getUses ()) {
37743806 if (originalUses.contains (use))
0 commit comments