Skip to content

Commit 7a31ea7

Browse files
committed
LoadableByAddress: fix handling of yield instructions which can result in invalid SIL
The code to handle yield instructions must be done earlier in `rewriteFunction` because it can add more instructions to the data structures, which also needs to be processed in `rewriteFunction`. https://bugs.swift.org/browse/SR-14994 rdar://77526343
1 parent 8296c58 commit 7a31ea7

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

lib/IRGen/LoadableByAddress.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,11 @@ static void rewriteFunction(StructLoweringState &pass,
20682068
pass.applies.append(currentModApplies.begin(), currentModApplies.end());
20692069
} while (repeat);
20702070

2071+
while (!pass.modYieldInsts.empty()) {
2072+
YieldInst *inst = pass.modYieldInsts.pop_back_val();
2073+
allocateAndSetAll(pass, allocator, inst, inst->getAllOperands());
2074+
}
2075+
20712076
for (SILInstruction *instr : pass.instsToMod) {
20722077
for (Operand &operand : instr->getAllOperands()) {
20732078
auto currOperand = operand.get();
@@ -2323,11 +2328,6 @@ static void rewriteFunction(StructLoweringState &pass,
23232328
retBuilder.createReturn(newRetTuple->getLoc(), newRetTuple);
23242329
instr->eraseFromParent();
23252330
}
2326-
2327-
while (!pass.modYieldInsts.empty()) {
2328-
YieldInst *inst = pass.modYieldInsts.pop_back_val();
2329-
allocateAndSetAll(pass, allocator, inst, inst->getAllOperands());
2330-
}
23312331
}
23322332

23332333
// Rewrite function return argument if it is a "function pointer"

test/IRGen/big_types_coroutine.sil

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,24 @@ bb2:
9797
abort_apply %4
9898
unwind
9999
}
100+
101+
// CHECK-LABEL: sil @test_yield_and_retain
102+
// CHECK: [[S:%[0-9]+]] = alloc_stack $BigStruct
103+
// CHECK: copy_addr [take] %0 to [initialization] [[S]]
104+
// CHECK: retain_value_addr [[S]]
105+
// CHECK: yield [[S]] : $*BigStruct
106+
// CHECK: // end sil function 'test_yield_and_retain'
107+
sil @test_yield_and_retain : $@convention(thin) @yield_once (@in_guaranteed BigStruct) -> @yields BigStruct {
108+
entry(%0 : $*BigStruct):
109+
%big = load %0 : $*BigStruct
110+
retain_value %big : $BigStruct
111+
yield %big : $BigStruct, resume resume, unwind unwind
112+
113+
resume:
114+
%ret = tuple ()
115+
return %ret : $()
116+
117+
unwind:
118+
unwind
119+
}
120+

0 commit comments

Comments
 (0)