Skip to content

Commit 64698ca

Browse files
committed
DeadCodeElimination: don't remove end_lifetime instructions with address operands
DCE cannot reason about values in memory. Fixes a memory lifetime verification error rdar://139779406
1 parent cb6e3db commit 64698ca

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

lib/SILOptimizer/Transforms/DeadCodeElimination.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,11 @@ void DCE::markLive() {
317317
break;
318318
}
319319
case SILInstructionKind::EndLifetimeInst: {
320+
if (I.getOperand(0)->getType().isAddress()) {
321+
// DCE cannot reason about values in memory.
322+
markInstructionLive(&I);
323+
break;
324+
}
320325
// The instruction is live only if it's operand value is also live
321326
addReverseDependency(I.getOperand(0), &I);
322327
break;

test/SILOptimizer/dead_code_elimination_ossa.sil

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ struct CAndBit {
2222
}
2323

2424
struct MO: ~Copyable {
25-
deinit
25+
var x: Int
26+
deinit
27+
}
28+
29+
struct Outer : ~Copyable {
30+
var x: MO
2631
}
2732

2833
sil @dummy : $@convention(thin) () -> ()
@@ -487,3 +492,18 @@ sil [ossa] @dont_delete_move_value_lexical : $@convention(thin) () -> () {
487492
%retval = tuple ()
488493
return %retval : $()
489494
}
495+
496+
// CHECK-LABEL: sil [ossa] @dont_remove_addr_end_lifetime :
497+
// CHECK: end_lifetime
498+
// CHECK-LABEL: } // end sil function 'dont_remove_addr_end_lifetime'
499+
sil [ossa] @dont_remove_addr_end_lifetime : $@convention(thin) (@owned Outer) -> () {
500+
bb0(%0 : @owned $Outer):
501+
%1 = alloc_stack $Outer
502+
store %0 to [init] %1 : $*Outer
503+
%3 = struct_element_addr %1 : $*Outer, #Outer.x
504+
end_lifetime %3 : $*MO
505+
dealloc_stack %1 : $*Outer
506+
%6 = tuple ()
507+
return %6 : $()
508+
}
509+

0 commit comments

Comments
 (0)