diff --git a/lib/SILOptimizer/Transforms/DestroyHoisting.cpp b/lib/SILOptimizer/Transforms/DestroyHoisting.cpp index 7887c69a9939e..3498f716a7110 100644 --- a/lib/SILOptimizer/Transforms/DestroyHoisting.cpp +++ b/lib/SILOptimizer/Transforms/DestroyHoisting.cpp @@ -95,6 +95,8 @@ class DestroyHoisting { void getUsedLocationsOfAddr(Bits &bits, SILValue addr); + void getUsedLocationsOfOperands(Bits &bits, SILInstruction *I); + void getUsedLocationsOfInst(Bits &bits, SILInstruction *Inst); void moveDestroys(MemoryDataflow &dataFlow); @@ -308,6 +310,12 @@ void DestroyHoisting::getUsedLocationsOfAddr(Bits &bits, SILValue addr) { } } +void DestroyHoisting::getUsedLocationsOfOperands(Bits &bits, SILInstruction *I) { + for (Operand &op : I->getAllOperands()) { + getUsedLocationsOfAddr(bits, op.get()); + } +} + // Set all bits of locations which instruction \p I is using. It's including // parent and sub-locations (see comment in getUsedLocationsOfAddr). void DestroyHoisting::getUsedLocationsOfInst(Bits &bits, SILInstruction *I) { @@ -319,18 +327,20 @@ void DestroyHoisting::getUsedLocationsOfInst(Bits &bits, SILInstruction *I) { } break; case SILInstructionKind::EndApplyInst: - // Operands passed to begin_apply are alive throughout the end_apply. - I = cast(I)->getBeginApply(); - LLVM_FALLTHROUGH; + // Operands passed to begin_apply are alive throughout an end_apply ... + getUsedLocationsOfOperands(bits, cast(I)->getBeginApply()); + break; + case SILInstructionKind::AbortApplyInst: + // ... or abort_apply. + getUsedLocationsOfOperands(bits, cast(I)->getBeginApply()); + break; case SILInstructionKind::LoadInst: case SILInstructionKind::StoreInst: case SILInstructionKind::CopyAddrInst: case SILInstructionKind::ApplyInst: case SILInstructionKind::TryApplyInst: case SILInstructionKind::YieldInst: - for (Operand &op : I->getAllOperands()) { - getUsedLocationsOfAddr(bits, op.get()); - } + getUsedLocationsOfOperands(bits, I); break; case SILInstructionKind::DebugValueAddrInst: case SILInstructionKind::DestroyAddrInst: diff --git a/test/SILOptimizer/destroy_hoisting.sil b/test/SILOptimizer/destroy_hoisting.sil index aaa2e606a0a4f..65a3df00257f1 100644 --- a/test/SILOptimizer/destroy_hoisting.sil +++ b/test/SILOptimizer/destroy_hoisting.sil @@ -230,3 +230,21 @@ bb1: %r = tuple () return %r : $() } + +// CHECK-LABEL: sil [ossa] @test_abort_apply +// CHECK: abort_apply +// CHECK-NEXT: destroy_addr %0 +// CHECK-NEXT: br bb1 +// CHECK: bb1: +// CHECK: return +sil [ossa] @test_abort_apply : $@convention(thin) (@in S, Int) -> () { +bb0(%0 : $*S, %1 : $Int): + %f = function_ref @coro : $@yield_once @convention(thin) (@in S) -> @yields @inout Int + (%i, %t) = begin_apply %f(%0) : $@yield_once @convention(thin) (@in S) -> @yields @inout Int + abort_apply %t + br bb1 +bb1: + destroy_addr %0 : $*S + %r = tuple () + return %r : $() +}