diff --git a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp index 098bc863880..9c98447e439 100644 --- a/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp +++ b/lib/SILOptimizer/Transforms/AllocBoxToStack.cpp @@ -53,9 +53,9 @@ static llvm::cl::opt AllocBoxToStackAnalyzeApply( // SIL Utilities for alloc_box Promotion //===----------------------------------------------------------------------===// -static SILValue stripOffCopyValue(SILValue V) { - while (auto *CVI = dyn_cast(V)) { - V = CVI->getOperand(); +static SILValue stripOffCopyAndBorrow(SILValue V) { + while (isa(V) || isa(V)) { + V = cast(V)->getOperand(0); } return V; } @@ -127,7 +127,7 @@ static bool addLastRelease(SILValue V, SILBasicBlock *BB, for (auto I = BB->rbegin(); I != BB->rend(); ++I) { if (isa(*I) || isa(*I) || isa(*I)) { - if (stripOffCopyValue(I->getOperand(0)) != V) + if (stripOffCopyAndBorrow(I->getOperand(0)) != V) continue; Releases.push_back(&*I); diff --git a/test/SILOptimizer/allocbox_to_stack_ownership.sil b/test/SILOptimizer/allocbox_to_stack_ownership.sil index a3bee9f466e..b2f9e988b34 100644 --- a/test/SILOptimizer/allocbox_to_stack_ownership.sil +++ b/test/SILOptimizer/allocbox_to_stack_ownership.sil @@ -469,6 +469,43 @@ bb0(%0 : $Int): unreachable } +sil [ossa] @closureWithBoxArg : $@convention(thin) (@guaranteed { var SomeClass }) -> () { +bb0(%0 : @guaranteed ${ var SomeClass }): + %r = tuple () + return %r : $() +} + +sil [ossa] @useClosure : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () { +bb0(%0 : @guaranteed $@callee_guaranteed () -> ()): + %r = tuple () + return %r : $() +} + +// CHECK-LABEL: sil [ossa] @finalReleaseWithBorrow +// CHECK: [[S:%[0-9]+]] = alloc_stack {{.*}}$SomeClass +// CHECK-NOT: destroy_addr +// CHECK: [[F:%[0-9]+]] = function_ref @useClosure +// CHECK: apply [[F]] +// CHECK: destroy_addr [[S]] +// CHECK: } // end sil function 'finalReleaseWithBorrow' +sil [ossa] @finalReleaseWithBorrow : $@convention(thin) (@owned SomeClass) -> () { +bb0(%0 : @owned $SomeClass): + %1 = alloc_box $ { var SomeClass } + %2 = begin_borrow %1 : ${ var SomeClass } + %1a = project_box %2 : ${ var SomeClass }, 0 + store %0 to [init] %1a : $*SomeClass + %3 = function_ref @closureWithBoxArg : $@convention(thin) (@guaranteed { var SomeClass }) -> () + %4 = copy_value %2 : ${ var SomeClass } + %5 = partial_apply [callee_guaranteed] %3(%4) : $@convention(thin) (@guaranteed { var SomeClass }) -> () + end_borrow %2 : ${ var SomeClass } + destroy_value %1 : ${ var SomeClass } + %6 = function_ref @useClosure : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () + apply %6(%5) : $@convention(thin) (@guaranteed @callee_guaranteed () -> ()) -> () + destroy_value %5 : $@callee_guaranteed () -> () + %10 = tuple () + return %10 : $() +} + // CHECK-LABEL: sil [transparent] [serialized] [ossa] @mightApply : $@convention(thin) (@owned @callee_owned () -> @out U) -> () sil [transparent] [serialized] [ossa] @mightApply : $@convention(thin) (@owned @callee_owned () -> @out U) -> () { // CHECK: bb0