Skip to content

Commit 6735659

Browse files
authored
Merge pull request #81207 from atrick/extend-coroutine
Fix LifetimeDependenceScopeFixup: extend scopes enclosing coroutines
2 parents cd54530 + 4a65be8 commit 6735659

File tree

3 files changed

+77
-3
lines changed

3 files changed

+77
-3
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/LifetimeDependenceScopeFixup.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -422,9 +422,6 @@ extension ScopeExtension {
422422
mutating func gatherYieldExtension(_ beginApply: BeginApplyInst) {
423423
// Create a separate ScopeExtension for each operand that the yielded value depends on.
424424
for operand in beginApply.parameterOperands {
425-
guard let dep = beginApply.resultDependence(on: operand), dep.isScoped else {
426-
continue
427-
}
428425
gatherExtensions(valueOrAddress: operand.value)
429426
}
430427
}

test/SILOptimizer/lifetime_dependence/lifetime_dependence_scope_fixup.swift

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,30 @@ func testReassignment(b: UnsafeMutableRawBufferPointer) {
300300
sub = span.update()
301301
use(sub)
302302
}
303+
304+
305+
// Coroutine nested in a mutable access scope.
306+
//
307+
// rdar://150275147 (Invalid SIL after lifetime dependence fixup involving coroutines)
308+
struct ArrayWrapper {
309+
private var a: [Int]
310+
311+
var array: [Int] {
312+
_read {
313+
yield a
314+
}
315+
_modify {
316+
yield &a
317+
}
318+
}
319+
}
320+
321+
@_silgen_name("gms")
322+
func getMutableSpan(_: inout [Int]) -> MutableSpan<Int>
323+
324+
func testWrite(_ w: inout ArrayWrapper) {
325+
var span = getMutableSpan(&w.array)
326+
for i in span.indices {
327+
span[i] = 0
328+
}
329+
}

test/SILOptimizer/lifetime_dependence/scope_fixup.sil

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ sil @useRawSpan : $@convention(thin) (@guaranteed RawSpan) -> ()
8080
sil @initHolder : $@convention(method) (@thin Holder.Type) -> @owned Holder
8181
sil @readAccess : $@yield_once @convention(method) (@guaranteed Holder) -> @lifetime(borrow 0) @yields @guaranteed NE
8282

83+
sil @yieldInoutHolder : $@yield_once @convention(method) (@inout Holder) -> @yields @inout Holder
84+
sil @yieldInoutNE : $@yield_once @convention(method) (@inout Holder) -> @lifetime(borrow 0) @owned NE
85+
8386
// NCContainer.wrapper._read:
8487
// var wrapper: Wrapper {
8588
// _read {
@@ -442,6 +445,53 @@ bb0(%0 : @owned $B):
442445
return %24
443446
}
444447

448+
// =============================================================================
449+
// Coroutine extension
450+
// =============================================================================
451+
452+
// Sink the inner end_apply and the outer end_access.
453+
//
454+
// CHECK-LABEL: sil hidden [ossa] @testCoroutineInsideAccess : $@convention(thin) (@inout Holder) -> () {
455+
// CHECK: bb0(%0 : $*Holder):
456+
// CHECK: [[BORROW:%[0-9]+]] = begin_borrow [lexical] [var_decl]
457+
// CHECK: [[ACCESS:%[0-9]+]] = begin_access [modify] [unknown] %0
458+
// CHECK: ({{.*}}, [[TOKEN:%[0-9]+]]) = begin_apply %{{.*}}([[ACCESS]]) : $@yield_once @convention(method) (@inout Holder) -> @yields @inout Holder
459+
// CHECK: apply
460+
// CHECK: [[MD:%[0-9]+]] = mark_dependence [unresolved] %10 on %7
461+
// CHECK: apply
462+
// CHECK: end_borrow
463+
// CHECK: end_access
464+
// CHECK: end_apply [[TOKEN]] as $()
465+
// CHECK: end_access [[ACCESS]]
466+
// CHECK: end_borrow [[BORROW]]
467+
// CHECK-LABEL: } // end sil function 'testCoroutineInsideAccess'
468+
sil hidden [ossa] @testCoroutineInsideAccess : $@convention(thin) (@inout Holder) -> () {// %0 "w"
469+
bb0(%0 : $*Holder):
470+
debug_value %0, var, name "w", argno 1, expr op_deref
471+
%2 = alloc_box ${ var NE }, var, name "span"
472+
%3 = begin_borrow [lexical] [var_decl] %2
473+
%4 = project_box %3, 0
474+
%5 = begin_access [modify] [unknown] %0
475+
%6 = function_ref @yieldInoutHolder : $@yield_once @convention(method) (@inout Holder) -> @yields @inout Holder
476+
(%7, %8) = begin_apply %6(%5) : $@yield_once @convention(method) (@inout Holder) -> @yields @inout Holder
477+
%9 = function_ref @getOwnedNEFromInout : $@convention(thin) (@inout Holder) -> @lifetime(borrow 0) @owned NE
478+
%10 = apply %9(%7) : $@convention(thin) (@inout Holder) -> @lifetime(borrow 0) @owned NE
479+
%11 = mark_dependence [unresolved] %10 on %7
480+
%12 = end_apply %8 as $()
481+
end_access %5
482+
store %11 to [init] %4
483+
%15 = begin_access [read] [unknown] %4
484+
%16 = load_borrow [unchecked] %15
485+
%17 = function_ref @useNE : $@convention(thin) (@guaranteed NE) -> ()
486+
%18 = apply %17(%16) : $@convention(thin) (@guaranteed NE) -> ()
487+
end_borrow %16
488+
end_access %15
489+
end_borrow %3
490+
destroy_value %2
491+
%99 = tuple ()
492+
return %99
493+
}
494+
445495
// =============================================================================
446496
// Return value extension
447497
// =============================================================================

0 commit comments

Comments
 (0)