Skip to content

Commit 6cf2bb4

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 15ce42a commit 6cf2bb4

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
@@ -1119,7 +1119,8 @@ specializeApplySite(SILOptFunctionBuilder &FuncBuilder, ApplySite Apply,
11191119
// the alloc_stack/dealloc_stack instructions where the alloc_box/
11201120
// destroy_value instructions are respectively. The copy_value
11211121
// can't keep the alloc_stack alive.
1122-
if ((svi = dyn_cast<CopyValueInst>(user))) {
1122+
if ((svi = dyn_cast<CopyValueInst>(user)) ||
1123+
(svi = dyn_cast<MoveValueInst>(user))) {
11231124
worklist.push(svi);
11241125
}
11251126
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)