Skip to content

Commit 822fd8a

Browse files
authored
Merge pull request #65152 from gottesmm/release/5.9/106164128
[5.9][move-only] Handle terminator users like yield when converting borrow -> destructure.
2 parents 9194aa4 + db87701 commit 822fd8a

File tree

4 files changed

+84
-0
lines changed

4 files changed

+84
-0
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,17 @@ bool GatherUsesVisitor::visitUse(Operand *op, AccessUseType useTy) {
17841784
}
17851785
}
17861786

1787+
if (auto *yi = dyn_cast<YieldInst>(user)) {
1788+
if (yi->getYieldInfoForOperand(*op).isGuaranteed()) {
1789+
auto leafRange = TypeTreeLeafTypeRange::get(op->get(), getRootAddress());
1790+
if (!leafRange)
1791+
return false;
1792+
1793+
useState.livenessUses.insert({user, *leafRange});
1794+
return true;
1795+
}
1796+
}
1797+
17871798
if (auto *pas = dyn_cast<PartialApplyInst>(user)) {
17881799
if (pas->isOnStack()) {
17891800
LLVM_DEBUG(llvm::dbgs() << "Found on stack partial apply!\n");

lib/SILOptimizer/Mandatory/MoveOnlyBorrowToDestructureUtils.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,14 @@ void Implementation::rewriteUses(InstructionDeleter *deleter) {
11831183
SILBuilderWithScope endBuilder(inst);
11841184
endBuilder.createEndBorrow(getSafeLoc(inst), borrow);
11851185
continue;
1186+
} else {
1187+
// Otherwise, put the end_borrow.
1188+
for (auto *succBlock : ti->getSuccessorBlocks()) {
1189+
auto *nextInst = &succBlock->front();
1190+
SILBuilderWithScope endBuilder(nextInst);
1191+
endBuilder.createEndBorrow(getSafeLoc(nextInst), borrow);
1192+
}
1193+
continue;
11861194
}
11871195
}
11881196

test/SILOptimizer/moveonly_addresschecker_diagnostics.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2467,3 +2467,18 @@ func borrowAndConsumeAtSameTimeTest(x: __owned NonTrivialStruct) { // expected-e
24672467
// expected-note @-1 {{consuming use here}}
24682468
// expected-note @-2 {{non-consuming use here}}
24692469
}
2470+
2471+
////////////////
2472+
// Yield Test //
2473+
////////////////
2474+
2475+
func yieldTest() {
2476+
// Make sure we do not crash on this.
2477+
@_moveOnly
2478+
struct S {
2479+
var c = CopyableKlass()
2480+
var c2: CopyableKlass {
2481+
_read { yield c }
2482+
}
2483+
}
2484+
}

test/SILOptimizer/moveonly_borrow_to_destructure_transform.sil

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,3 +1027,53 @@ bbCont:
10271027
%9999 = tuple()
10281028
return %9999 : $()
10291029
}
1030+
1031+
// CHECK-LABEL: sil [ossa] @yieldTest : $@yield_once @convention(method) (@guaranteed KlassPair) -> @yields @guaranteed Klass {
1032+
// CHECK: bb0([[INPUT_ARG:%.*]] :
1033+
// CHECK: [[COPIED_INPUT_ARG:%.*]] = copy_value [[INPUT_ARG]]
1034+
// CHECK: [[ARG:%.*]] = mark_must_check [no_consume_or_assign] [[COPIED_INPUT_ARG]]
1035+
// CHECK: [[DESTR_COPY:%.*]] = copy_value [[ARG]]
1036+
// CHECK: [[DESTR_COPY_BORROW:%.*]] = begin_borrow [[DESTR_COPY]]
1037+
// CHECK: [[EXT:%.*]] = struct_extract [[DESTR_COPY_BORROW]]
1038+
// CHECK: yield [[EXT]] : $Klass, resume [[BBLHS:bb[0-9]+]], unwind [[BBRHS:bb[0-9]+]]
1039+
//
1040+
// CHECK: [[BBLHS]]:
1041+
// CHECK-NEXT: end_borrow [[DESTR_COPY_BORROW]]
1042+
// CHECK-NEXT: destroy_value [[DESTR_COPY]]
1043+
// CHECK-NEXT: // function_ref
1044+
// CHECK-NEXT: function_ref
1045+
// CHECK-NEXT: destroy_value [[ARG]]
1046+
// CHECK-NEXT: tuple
1047+
// CHECK-NEXT: return
1048+
//
1049+
// CHECK: [[BBRHS]]:
1050+
// CHECK-NEXT: end_borrow [[DESTR_COPY_BORROW]]
1051+
// CHECK-NEXT: destroy_value [[DESTR_COPY]]
1052+
// CHECK-NEXT: // function_ref
1053+
// CHECK-NEXT: function_ref
1054+
// CHECK-NEXT: destroy_value [[ARG]]
1055+
// CHECK-NEXT: unwind
1056+
// CHECK: } // end sil function 'yieldTest'
1057+
sil [ossa] @yieldTest : $@yield_once @convention(method) (@guaranteed KlassPair) -> @yields @guaranteed Klass {
1058+
bb0(%0 : @guaranteed $KlassPair):
1059+
%1 = copy_value %0 : $KlassPair
1060+
%2 = mark_must_check [no_consume_or_assign] %1 : $KlassPair
1061+
%3 = begin_borrow %2 : $KlassPair
1062+
%4 = struct_extract %3 : $KlassPair, #KlassPair.lhs
1063+
yield %4 : $Klass, resume bb1, unwind bb2
1064+
1065+
bb1:
1066+
// Dead instruction just to show that we move the end_borrow before this.
1067+
%f = function_ref @misc_use : $@convention(thin) () -> ()
1068+
end_borrow %3 : $KlassPair
1069+
destroy_value %2 : $KlassPair
1070+
%5 = tuple ()
1071+
return %5 : $()
1072+
1073+
bb2:
1074+
// Dead instruction just to show that we move the end_borrow before this.
1075+
%f2 = function_ref @misc_use : $@convention(thin) () -> ()
1076+
end_borrow %3 : $KlassPair
1077+
destroy_value %2 : $KlassPair
1078+
unwind
1079+
}

0 commit comments

Comments
 (0)