mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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
This commit is contained in:
@@ -429,6 +429,14 @@ bool SILCombiner::doOneIteration(SILFunction &F, unsigned Iteration) {
|
||||
return MadeChange;
|
||||
}
|
||||
|
||||
static bool hasAddressOperands(SILInstruction *inst) {
|
||||
for (Operand *op : inst->getRealOperands()) {
|
||||
if (op->get()->getType().isAddress())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SILCombiner::processInstruction(SILInstruction *I,
|
||||
SILCombineCanonicalize &scCanonicalize,
|
||||
bool &MadeChange) {
|
||||
@@ -467,6 +475,15 @@ void SILCombiner::processInstruction(SILInstruction *I,
|
||||
if (auto *svi = dyn_cast<SingleValueInstruction>(I)) {
|
||||
if (auto fwdOp = ForwardingOperation(svi)) {
|
||||
if (fwdOp.getSingleForwardingOperand() &&
|
||||
|
||||
// Don't risk sinking instructions with address operands out of the
|
||||
// addressed memory's lifetime. E.g:
|
||||
// ```
|
||||
// %3 = mark_dependence %2 on %1 : $*T // must not be moved after the destroy_addr
|
||||
// destroy_addr %1
|
||||
// ```
|
||||
!hasAddressOperands(svi) &&
|
||||
|
||||
SILValue(svi)->getOwnershipKind() == OwnershipKind::Owned) {
|
||||
// Try to sink the value. If we sank the value and deleted it,
|
||||
// return. If we didn't optimize or sank but we are still able to
|
||||
|
||||
@@ -5577,4 +5577,24 @@ bb0(%0 : @guaranteed $String):
|
||||
return %1
|
||||
}
|
||||
|
||||
// CHECK-LABEL: sil [ossa] @dont_sink_mark_dependence_out_of_memory_lifetime :
|
||||
// CHECK: mark_dependence
|
||||
// CHECK: bb1:
|
||||
// CHECK: } // end sil function 'dont_sink_mark_dependence_out_of_memory_lifetime'
|
||||
sil [ossa] @dont_sink_mark_dependence_out_of_memory_lifetime : $@convention(thin) (@owned Klass, @owned Klass) -> () {
|
||||
bb0(%0 : @owned $Klass, %1 : @owned $Klass):
|
||||
%2 = alloc_stack $Klass
|
||||
store %1 to [init] %2
|
||||
%4 = mark_dependence %0 on %2
|
||||
destroy_addr %2
|
||||
br bb1
|
||||
|
||||
bb1:
|
||||
destroy_value %4
|
||||
dealloc_stack %2
|
||||
%9 = tuple ()
|
||||
return %9
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user