Skip to content

Commit e677282

Browse files
authored
Merge pull request #84760 from eeckstein/fix-sil-combine
SILCombine: be careful about deleting trivially dead `destructure_struct` instructions
2 parents 1061f95 + f57278f commit e677282

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,14 @@ bool swift::isInstructionTriviallyDead(SILInstruction *inst) {
179179
if (isa<BorrowedFromInst>(inst))
180180
return false;
181181

182+
// A dead `destructure_struct` with an owned argument can appear for a non-copyable or
183+
// non-escapable struct which has only trivial elements. The instruction is not trivially
184+
// dead because it ends the lifetime of its operand.
185+
if (isa<DestructureStructInst>(inst) &&
186+
inst->getOperand(0)->getOwnershipKind() == OwnershipKind::Owned) {
187+
return false;
188+
}
189+
182190
// These invalidate enums so "write" memory, but that is not an essential
183191
// operation so we can remove these if they are trivially dead.
184192
if (isa<UncheckedTakeEnumDataAddrInst>(inst))

test/SILOptimizer/sil_combine_moveonly.sil

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ struct S : ~Copyable {
1111
deinit {}
1212
}
1313

14+
struct S2 : ~Copyable {
15+
@_hasStorage var a: Int { get set }
16+
@_hasStorage var b: Int { get set }
17+
}
18+
1419
struct FileDescriptor: ~Copyable {
1520
var fd: Builtin.Int64
1621

@@ -169,3 +174,14 @@ bb0:
169174
%13 = tuple ()
170175
return %13
171176
}
177+
178+
// CHECK-LABEL: sil [ossa] @dont_remove_destructure_struct_of_non_copyable :
179+
// CHECK: destructure_struct
180+
// CHECK-LABEL: } // end sil function 'dont_remove_destructure_struct_of_non_copyable'
181+
sil [ossa] @dont_remove_destructure_struct_of_non_copyable : $@convention(method) (@owned S2) -> () {
182+
bb0(%0 : @owned $S2):
183+
(%1, %2) = destructure_struct %0
184+
%r = tuple ()
185+
return %r
186+
}
187+

0 commit comments

Comments
 (0)