Skip to content

Commit 75ce4c7

Browse files
eecksteinkavon
authored andcommitted
MoveOnlyDeinitInsertion: don't call the deinit if the destroy is preceeded by a drop_deinit
rdar://105798769
1 parent a7ee751 commit 75ce4c7

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

lib/SILOptimizer/Mandatory/MoveOnlyDeinitInsertion.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ static bool performTransform(SILFunction &fn) {
6262

6363
if (auto *dvi = dyn_cast<DestroyValueInst>(inst)) {
6464
auto destroyType = dvi->getOperand()->getType();
65-
if (destroyType.isMoveOnlyNominalType()) {
65+
if (destroyType.isMoveOnlyNominalType() &&
66+
!isa<DropDeinitInst>(lookThroughOwnershipInsts(dvi->getOperand()))) {
6667
LLVM_DEBUG(llvm::dbgs() << "Handling: " << *dvi);
6768
auto *nom = destroyType.getNominalOrBoundGenericNominal();
6869
assert(nom);
@@ -88,7 +89,8 @@ static bool performTransform(SILFunction &fn) {
8889

8990
if (auto *dai = dyn_cast<DestroyAddrInst>(inst)) {
9091
auto destroyType = dai->getOperand()->getType();
91-
if (destroyType.isLoadable(fn) && destroyType.isMoveOnlyNominalType()) {
92+
if (destroyType.isLoadable(fn) && destroyType.isMoveOnlyNominalType() &&
93+
!isa<DropDeinitInst>(dai->getOperand())) {
9294
LLVM_DEBUG(llvm::dbgs() << "Handling: " << *dai);
9395
auto *nom = destroyType.getNominalOrBoundGenericNominal();
9496
assert(nom);

test/SILOptimizer/moveonly_deinit_insertion.sil

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,48 @@ bb6:
309309
return %14 : $()
310310
}
311311

312+
//===----------------------------------------------------------------------===//
313+
// drop_deinit Tests
314+
//===----------------------------------------------------------------------===//
315+
316+
// CHECK-LABEL: sil [ossa] @dropDeinitOnStruct : $@convention(thin) (@owned TrivialStruct) -> () {
317+
// CHECK: %1 = drop_deinit %0
318+
// CHECK-NEXT: destroy_value %1
319+
// CHECK: } // end sil function 'dropDeinitOnStruct'
320+
sil [ossa] @dropDeinitOnStruct : $@convention(thin) (@owned TrivialStruct) -> () {
321+
bb0(%0 : @owned $TrivialStruct):
322+
%1 = drop_deinit %0 : $TrivialStruct
323+
destroy_value %1 : $TrivialStruct
324+
%9999 = tuple()
325+
return %9999 : $()
326+
}
327+
328+
// CHECK-LABEL: sil [ossa] @dropDeinitOnMovedStruct : $@convention(thin) (@owned TrivialStruct) -> () {
329+
// CHECK: %1 = drop_deinit %0
330+
// CHECK-NEXT: %2 = move_value %1
331+
// CHECK-NEXT: destroy_value %2
332+
// CHECK: } // end sil function 'dropDeinitOnMovedStruct'
333+
sil [ossa] @dropDeinitOnMovedStruct : $@convention(thin) (@owned TrivialStruct) -> () {
334+
bb0(%0 : @owned $TrivialStruct):
335+
%1 = drop_deinit %0 : $TrivialStruct
336+
%2 = move_value %1 : $TrivialStruct
337+
destroy_value %2 : $TrivialStruct
338+
%9999 = tuple()
339+
return %9999 : $()
340+
}
341+
342+
// CHECK-LABEL: sil [ossa] @dropDeinitOnIndirectStruct : $@convention(thin) (@in TrivialStruct) -> () {
343+
// CHECK: %1 = drop_deinit %0
344+
// CHECK-NEXT: destroy_addr %1
345+
// CHECK: } // end sil function 'dropDeinitOnIndirectStruct'
346+
sil [ossa] @dropDeinitOnIndirectStruct : $@convention(thin) (@in TrivialStruct) -> () {
347+
bb0(%0 : $*TrivialStruct):
348+
%1 = drop_deinit %0 : $*TrivialStruct
349+
destroy_addr %1 : $*TrivialStruct
350+
%9999 = tuple()
351+
return %9999 : $()
352+
}
353+
312354
sil @$s4main5KlassCfD : $@convention(method) (@owned Klass) -> ()
313355
sil @$s4main5KlassCACycfc : $@convention(method) (@owned Klass) -> @owned Klass
314356
sil @$s4main5KlassCfd : $@convention(method) (@guaranteed Klass) -> @owned Builtin.NativeObject

0 commit comments

Comments
 (0)