Skip to content

Commit c4b6710

Browse files
authored
Merge pull request #66279 from atrick/fix-dropdeinit-sideeffect
Fix drop_deinit side effects.
2 parents 3cd653d + af49f62 commit c4b6710

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

include/swift/SIL/SILNodes.def

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,15 @@ ABSTRACT_VALUE_AND_INST(SingleValueInstruction, ValueBase, SILInstruction)
461461
// effects relative to other OSSA values like copy_value.
462462
SINGLE_VALUE_INST(MoveValueInst, move_value, SingleValueInstruction, None,
463463
DoesNotRelease)
464-
SINGLE_VALUE_INST(DropDeinitInst, drop_deinit, SingleValueInstruction, None,
465-
DoesNotRelease)
464+
// A drop_deinit has no user-level side effects. It does, however, change the
465+
// information about the owenership of its operand, and therefore cannot be
466+
// arbitrarily deleted. It effectively wraps the type of the operand so that
467+
// the resulting value is an equivalent type without a user-defined deinit.
468+
//
469+
// TODO: Add an OwnershipEffect type of side effect for instructions like
470+
// drop_deinit to indicate their ownership effects.
471+
SINGLE_VALUE_INST(DropDeinitInst, drop_deinit, SingleValueInstruction,
472+
MayHaveSideEffects, DoesNotRelease)
466473
// A canary value inserted by a SIL generating frontend to signal to the move
467474
// checker to check a specific value. Valid only in Raw SIL. The relevant
468475
// checkers should remove the mark_must_check instruction after successfully

lib/SIL/Utils/MemAccessUtils.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2698,6 +2698,7 @@ void swift::visitAccessedAddress(SILInstruction *I,
26982698
case SILInstructionKind::DeinitExistentialValueInst:
26992699
case SILInstructionKind::DestroyAddrInst:
27002700
case SILInstructionKind::DestroyValueInst:
2701+
case SILInstructionKind::DropDeinitInst:
27012702
case SILInstructionKind::EndAccessInst:
27022703
case SILInstructionKind::EndApplyInst:
27032704
case SILInstructionKind::EndBorrowInst:

test/SILOptimizer/dead_code_elimination_ossa.sil

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ struct CAndBit {
1818
var bit: Int1
1919
}
2020

21+
@_moveOnly
22+
struct MO {
23+
deinit
24+
}
25+
2126
sil @dummy : $@convention(thin) () -> ()
2227

2328
// CHECK-LABEL: sil [ossa] @dead1 :
@@ -407,3 +412,23 @@ exit:
407412
%retval = tuple ()
408413
return %retval : $()
409414
}
415+
416+
// Test that DCE does not eliminate a drop_deinit.
417+
//
418+
// rdar://109863801 ([move-only] DCE removes drop_deinit, so
419+
// user-defined deinitializers call themselves recursively at -O)
420+
//
421+
// CHECK-LABEL: sil hidden [ossa] @testDropDeinit : $@convention(method) (@owned MO) -> () {
422+
// CHECK: [[DROP:%.*]] = drop_deinit %0 : $MO
423+
// CHECK: end_lifetime [[DROP]] : $MO
424+
// CHECK-LABEL: } // end sil function 'testDropDeinit'
425+
//
426+
// MO.deinit
427+
sil hidden [ossa] @testDropDeinit : $@convention(method) (@owned MO) -> () {
428+
bb0(%0 : @owned $MO):
429+
debug_value %0 : $MO, let, name "self", argno 1, implicit
430+
%61 = drop_deinit %0 : $MO
431+
end_lifetime %61 : $MO
432+
%63 = tuple ()
433+
return %63 : $()
434+
}

0 commit comments

Comments
 (0)