Skip to content

Commit 91c2dea

Browse files
committed
SILCombine: don't sink forwarding instructions with address operands
We don't do memory lifetime analysis for this peephole optimization. Therefore we can't risk sinking instructions with address operands out of the addressed memory's lifetime. For example: ``` %3 = mark_dependence %2 on %1 : $*T // must not be moved after the destroy_addr destroy_addr %1 ``` Fixes a verifier crash rdar://166240751
1 parent 6e5ba7a commit 91c2dea

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

lib/SILOptimizer/SILCombiner/SILCombine.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,14 @@ bool SILCombiner::doOneIteration(SILFunction &F, unsigned Iteration) {
429429
return MadeChange;
430430
}
431431

432+
static bool hasAddressOperands(SILInstruction *inst) {
433+
for (Operand *op : inst->getRealOperands()) {
434+
if (op->get()->getType().isAddress())
435+
return true;
436+
}
437+
return false;
438+
}
439+
432440
void SILCombiner::processInstruction(SILInstruction *I,
433441
SILCombineCanonicalize &scCanonicalize,
434442
bool &MadeChange) {
@@ -467,6 +475,15 @@ void SILCombiner::processInstruction(SILInstruction *I,
467475
if (auto *svi = dyn_cast<SingleValueInstruction>(I)) {
468476
if (auto fwdOp = ForwardingOperation(svi)) {
469477
if (fwdOp.getSingleForwardingOperand() &&
478+
479+
// Don't risk sinking instructions with address operands out of the
480+
// addressed memory's lifetime. E.g:
481+
// ```
482+
// %3 = mark_dependence %2 on %1 : $*T // must not be moved after the destroy_addr
483+
// destroy_addr %1
484+
// ```
485+
!hasAddressOperands(svi) &&
486+
470487
SILValue(svi)->getOwnershipKind() == OwnershipKind::Owned) {
471488
// Try to sink the value. If we sank the value and deleted it,
472489
// return. If we didn't optimize or sank but we are still able to

test/SILOptimizer/sil_combine_ossa.sil

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5577,4 +5577,24 @@ bb0(%0 : @guaranteed $String):
55775577
return %1
55785578
}
55795579

5580+
// CHECK-LABEL: sil [ossa] @dont_sink_mark_dependence_out_of_memory_lifetime :
5581+
// CHECK: mark_dependence
5582+
// CHECK: bb1:
5583+
// CHECK: } // end sil function 'dont_sink_mark_dependence_out_of_memory_lifetime'
5584+
sil [ossa] @dont_sink_mark_dependence_out_of_memory_lifetime : $@convention(thin) (@owned Klass, @owned Klass) -> () {
5585+
bb0(%0 : @owned $Klass, %1 : @owned $Klass):
5586+
%2 = alloc_stack $Klass
5587+
store %1 to [init] %2
5588+
%4 = mark_dependence %0 on %2
5589+
destroy_addr %2
5590+
br bb1
5591+
5592+
bb1:
5593+
destroy_value %4
5594+
dealloc_stack %2
5595+
%9 = tuple ()
5596+
return %9
5597+
}
5598+
5599+
55805600

0 commit comments

Comments
 (0)