Skip to content

Commit 2328b36

Browse files
committed
[AllocBoxToStack] PAI frontier looks thru moves.
When determining where to destroy a captured alloc_box, the frontier of the capturing partial_apply is computed. Previously, that computation just used the uses of the partial_apply. If the partial_apply were moved and the original destroyed before the apply, however, the result would be a miscompile where the destroy_addr/dealloc_stack for the alloc_stack to which the alloc_box was promoted was destroyed before the apply of the closure which used the address.
1 parent ebac2e4 commit 2328b36

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

lib/SILOptimizer/Transforms/AllocBoxToStack.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1110,7 +1110,8 @@ specializeApplySite(SILOptFunctionBuilder &FuncBuilder, ApplySite Apply,
11101110
for (auto *use : svi->getUses()) {
11111111
auto *user = use->getUser();
11121112
SingleValueInstruction *svi;
1113-
if ((svi = dyn_cast<CopyValueInst>(user))) {
1113+
if ((svi = dyn_cast<CopyValueInst>(user)) ||
1114+
(svi = dyn_cast<MoveValueInst>(user))) {
11141115
worklist.push(svi);
11151116
}
11161117
users.push_back(user);

test/SILOptimizer/allocboxtostack_localapply_ossa.sil

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,3 +524,27 @@ bb0:
524524
%retval = tuple ()
525525
return %retval : $()
526526
}
527+
528+
// CHECK-LABEL: sil [ossa] @test_move_applied : {{.*}} {
529+
// CHECK: [[CLOSURE:%[^,]+]] = partial_apply
530+
// CHECK: [[MOVE:%[^,]+]] = move_value [[CLOSURE]]
531+
// CHECK: apply [[MOVE]]()
532+
// CHECK: destroy_addr
533+
// CHECK: dealloc_stack
534+
// CHECK-LABEL: } // end sil function 'test_move_applied'
535+
sil [ossa] @test_move_applied : $@convention(thin) () -> () {
536+
bb0:
537+
%box = alloc_box ${ var C }, var, name "x"
538+
%addr = project_box %box : ${ var C }, 0
539+
%getC = function_ref @getC : $@convention(thin) () -> (@owned C)
540+
%c = apply %getC() : $@convention(thin) () -> (@owned C)
541+
store %c to [init] %addr : $*C
542+
543+
%borrow_int_box = function_ref @borrow_c_box : $@convention(thin) (@guaranteed { var C }) -> ()
544+
%closure = partial_apply [callee_guaranteed] %borrow_int_box(%box) : $@convention(thin) (@guaranteed { var C }) -> ()
545+
%move = move_value %closure : $@callee_guaranteed () -> ()
546+
apply %move() : $@callee_guaranteed () -> ()
547+
destroy_value %move : $@callee_guaranteed () -> ()
548+
%retval = tuple ()
549+
return %retval : $()
550+
}

0 commit comments

Comments
 (0)