Skip to content

Commit f8b5bac

Browse files
committed
Fix CapturePromotion handling of mark_dependence
1 parent a0b2ae9 commit f8b5bac

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

lib/SILOptimizer/Mandatory/CapturePromotion.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1210,16 +1210,16 @@ static bool findEscapeOrMutationUses(Operand *op,
12101210
}
12111211

12121212
// A mark_dependence user on a partial_apply is safe.
1213-
if (auto *mdi = dyn_cast<MarkDependenceInst>(user)) {
1214-
if (mdi->getBase() == op->get()) {
1215-
auto parent = mdi->getValue();
1216-
while ((mdi = dyn_cast<MarkDependenceInst>(parent))) {
1217-
parent = mdi->getValue();
1213+
if (auto *userMDI = dyn_cast<MarkDependenceInst>(user)) {
1214+
if (userMDI->getBase() == op->get()) {
1215+
auto parent = userMDI->getValue();
1216+
while (auto *parentMDI = dyn_cast<MarkDependenceInst>(parent)) {
1217+
parent = parentMDI->getValue();
12181218
}
12191219
if (isa<PartialApplyInst>(parent))
12201220
return false;
12211221
state.accumulatedEscapes.push_back(
1222-
&mdi->getOperandRef(MarkDependenceInst::Value));
1222+
&userMDI->getOperandRef(MarkDependenceInst::Value));
12231223
return true;
12241224
}
12251225
}

test/SILOptimizer/capture_promotion_ownership.sil

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
// RUN: %target-sil-opt -enable-sil-verify-all %s -capture-promotion | %FileCheck %s
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -capture-promotion \
2+
// RUN: -enable-experimental-feature NonescapableTypes -enable-experimental-feature NoncopyableGenerics -module-name Swift \
3+
// RUN: | %FileCheck %s
24

35
// Check to make sure that the process of promoting closure captures results in
46
// a correctly cloned and modified closure function body. This test
@@ -25,6 +27,10 @@ struct Baz {
2527
var x: Int
2628
}
2729

30+
@_marker public protocol Escapable { }
31+
32+
struct Nonescapable: ~Escapable {}
33+
2834
sil @convert_from_integer_literal : $@convention(thin) (Builtin.Word, @thin Int.Type) -> Int
2935
sil @foo_allocating_init : $@convention(thin) (@thick Foo.Type) -> @owned Foo
3036
sil @baz_init : $@convention(thin) (@thin Baz.Type) -> @owned Baz
@@ -514,3 +520,36 @@ bb0(%0 : @owned $Builtin.NativeObject):
514520
%pai = partial_apply %3(%1) : $@convention(thin) (@guaranteed { var Builtin.NativeObject }) -> ()
515521
return %pai : $@callee_owned () -> ()
516522
}
523+
524+
sil @foo_dependence : $@convention(thin) (@guaranteed Foo) -> _scope(1) @owned Nonescapable
525+
sil @use_nonescapable : $@convention(thin) (@guaranteed Nonescapable) -> ()
526+
527+
// Test that the pass does not crash when it sees a mark_dependence on an alloc_box base that does not have a partial_apply value.
528+
sil [ossa] @test_capture_promotion_mark_dependence : $@convention(thin) () -> () {
529+
bb0:
530+
%6 = alloc_box ${ let Foo }, let, name "c"
531+
%7 = begin_borrow [lexical] [var_decl] %6 : ${ let Foo }
532+
%8 = project_box %7 : ${ let Foo }, 0
533+
%9 = metatype $@thick Foo.Type
534+
535+
%12 = function_ref @foo_allocating_init : $@convention(thin) (@thick Foo.Type) -> @owned Foo
536+
%13 = apply %12(%9) : $@convention(thin) (@thick Foo.Type) -> @owned Foo
537+
store %13 to [init] %8 : $*Foo
538+
%16 = load_borrow %8 : $*Foo
539+
540+
%17 = function_ref @foo_dependence : $@convention(thin) (@guaranteed Foo) -> _scope(1) @owned Nonescapable
541+
%18 = apply %17(%16) : $@convention(thin) (@guaranteed Foo) -> _scope(1) @owned Nonescapable
542+
543+
%19 = mark_dependence [unresolved] %18 : $Nonescapable on %6 : ${ let Foo }
544+
%20 = move_value [var_decl] %19 : $Nonescapable
545+
end_borrow %16 : $Foo
546+
547+
%23 = function_ref @use_nonescapable : $@convention(thin) (@guaranteed Nonescapable) -> ()
548+
%24 = apply %23(%20) : $@convention(thin) (@guaranteed Nonescapable) -> ()
549+
destroy_value %20 : $Nonescapable
550+
end_borrow %7 : ${ let Foo }
551+
552+
destroy_value %6 : ${ let Foo }
553+
%28 = tuple ()
554+
return %28 : $()
555+
}

0 commit comments

Comments
 (0)