Skip to content

Commit ba424cc

Browse files
committed
[AddressLowering] Omit dealloc_stack in dead ends.
It is valid for owned values not to be destroyed on paths terminating in unreachable. Similarly, it is valid for storage not to be deallocated on paths terminating in unreachable. However, it is _not_ valid for storage to be deallocated before being deinitialized, even in paths terminating in unreachable. Consequently, when AddressLowering, dealloc_stacks must not be created in dead-end blocks: because the input OSSA may not destroy an owned value, the output may not deinitialize owned storage; so a dealloc_stack in an unreachable block could dealloc storage which was not deinitialized.
1 parent 9774e98 commit ba424cc

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

lib/SILOptimizer/Mandatory/AddressLowering.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@
149149
#include "swift/SIL/SILInstruction.h"
150150
#include "swift/SIL/SILValue.h"
151151
#include "swift/SIL/SILVisitor.h"
152+
#include "swift/SILOptimizer/Analysis/DeadEndBlocksAnalysis.h"
152153
#include "swift/SILOptimizer/Analysis/PostOrderAnalysis.h"
153154
#include "swift/SILOptimizer/PassManager/Transforms.h"
154155
#include "swift/SILOptimizer/Utils/BasicBlockOptUtils.h"
@@ -413,6 +414,9 @@ struct AddressLoweringState {
413414
// Dominators remain valid throughout this pass.
414415
DominanceInfo *domInfo;
415416

417+
// Dead-end blocks remain valid through this pass.
418+
DeadEndBlocks *deBlocks;
419+
416420
InstructionDeleter deleter;
417421

418422
// All opaque values mapped to their associated storage.
@@ -441,9 +445,10 @@ struct AddressLoweringState {
441445
// Handle moves from a phi's operand storage to the phi storage.
442446
std::unique_ptr<PhiRewriter> phiRewriter;
443447

444-
AddressLoweringState(SILFunction *function, DominanceInfo *domInfo)
448+
AddressLoweringState(SILFunction *function, DominanceInfo *domInfo,
449+
DeadEndBlocks *deBlocks)
445450
: function(function), loweredFnConv(getLoweredFnConv(function)),
446-
domInfo(domInfo) {
451+
domInfo(domInfo), deBlocks(deBlocks) {
447452
for (auto &block : *function) {
448453
if (block.getTerminator()->isFunctionExiting())
449454
exitingInsts.push_back(block.getTerminator());
@@ -1332,6 +1337,8 @@ void OpaqueStorageAllocation::finalizeOpaqueStorage() {
13321337
// a use projection.
13331338
computeDominatedBoundaryBlocks(alloc->getParent(), pass.domInfo, boundary);
13341339
for (SILBasicBlock *deallocBlock : boundary) {
1340+
if (pass.deBlocks->isDeadEnd(deallocBlock))
1341+
continue;
13351342
auto deallocBuilder = pass.getBuilder(deallocBlock->back().getIterator());
13361343
deallocBuilder.createDeallocStack(pass.genLoc(), alloc);
13371344
}
@@ -3859,8 +3866,10 @@ void AddressLowering::runOnFunction(SILFunction *function) {
38593866
removeUnreachableBlocks(*function);
38603867

38613868
auto *dominance = PM->getAnalysis<DominanceAnalysis>();
3869+
auto *deadEnds = PM->getAnalysis<DeadEndBlocksAnalysis>();
38623870

3863-
AddressLoweringState pass(function, dominance->get(function));
3871+
AddressLoweringState pass(function, dominance->get(function),
3872+
deadEnds->get(function));
38643873

38653874
// ## Step #1: Map opaque values
38663875
//

test/SILOptimizer/address_lowering.sil

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1740,6 +1740,19 @@ bb2:
17401740
unwind
17411741
}
17421742

1743+
// CHECK-LABEL: sil [ossa] @testUnreachable1NoDestroy : {{.*}} {
1744+
// CHECK: [[STORAGE:%[^,]+]] = alloc_stack $T
1745+
// CHECK: apply undef<T>([[STORAGE]])
1746+
// CHECK: apply undef<T>([[STORAGE]])
1747+
// CHECK: unreachable
1748+
// CHECK-LABEL: } // end sil function 'testUnreachable1NoDestroy'
1749+
sil [ossa] @testUnreachable1NoDestroy : $@convention(thin) <T> () -> () {
1750+
bb0:
1751+
%instance = apply undef<T>() : $@convention(thin) <τ> () -> @out τ
1752+
apply undef<T>(%instance) : $@convention(thin) <τ> (@in_guaranteed τ) -> ()
1753+
unreachable
1754+
}
1755+
17431756
sil [ossa] @use_T : $@convention(thin) <T> (@in T) -> ()
17441757

17451758
// CHECK-LABEL: sil [ossa] @test_checked_cast_br1 : $@convention(method) <T> (@in Any) -> () {

0 commit comments

Comments
 (0)