Skip to content

Commit 475ecca

Browse files
authored
Merge pull request #82476 from eeckstein/fix-temp-lvalue-elimination
TempLValueElimination: fix a stupid bug when combining `copy_addr` with a following `destroy_addr`
2 parents 3309f75 + abbe0e8 commit 475ecca

File tree

2 files changed

+35
-15
lines changed

2 files changed

+35
-15
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/TempLValueElimination.swift

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,7 @@ private extension FullApplySite {
216216
/// destroy_addr %source
217217
/// ```
218218
private func combineWithDestroy(copy: CopyAddrInst, _ context: FunctionPassContext) {
219-
guard !copy.isTakeOfSource,
220-
let destroy = copy.source.uses.users(ofType: DestroyAddrInst.self).first,
221-
destroy.parentBlock == copy.parentBlock
222-
else {
219+
guard !copy.isTakeOfSource else {
223220
return
224221
}
225222

@@ -228,20 +225,21 @@ private func combineWithDestroy(copy: CopyAddrInst, _ context: FunctionPassConte
228225
defer { debugInsts.deinitialize() }
229226

230227
for inst in InstructionList(first: copy.next) {
231-
if inst == destroy {
232-
break
233-
}
234-
if let debugInst = inst as? DebugValueInst, debugInst.operand.value == copy.source {
235-
debugInsts.append(debugInst)
236-
}
237-
if inst.mayReadOrWriteMemory {
228+
switch inst {
229+
case let destroy as DestroyAddrInst where destroy.destroyedAddress == copy.source:
230+
copy.set(isTakeOfSource: true, context)
231+
context.erase(instruction: destroy)
232+
// Don't let debug info think that the value is still valid after the `copy [take]`.
233+
context.erase(instructions: debugInsts)
238234
return
235+
case let debugInst as DebugValueInst where debugInst.operand.value == copy.source:
236+
debugInsts.append(debugInst)
237+
default:
238+
if inst.mayReadOrWriteMemory {
239+
return
240+
}
239241
}
240242
}
241-
copy.set(isTakeOfSource: true, context)
242-
context.erase(instruction: destroy)
243-
// Don't let debug info think that the value is still valid after the `copy [take]`.
244-
context.erase(instructions: debugInsts)
245243
}
246244

247245
private extension Value {

test/SILOptimizer/templvalueopt_ossa.sil

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,3 +630,25 @@ bb0(%0 : @guaranteed $__ContiguousArrayStorageBase):
630630
return %12
631631
}
632632

633+
// CHECK-LABEL: sil [ossa] @destroy_before_copy :
634+
// CHECK: bb1:
635+
// CHECK-NEXT: destroy_addr
636+
// CHECK-LABEL: } // end sil function 'destroy_before_copy'
637+
sil [ossa] @destroy_before_copy : $@convention(thin) (@in_guaranteed Child) -> @out Child {
638+
bb0(%0 : $*Child, %1 : $*Child):
639+
%2 = alloc_stack $Child
640+
copy_addr %1 to [init] %2
641+
br bb1
642+
643+
bb1:
644+
destroy_addr %2
645+
copy_addr %1 to [init] %2
646+
copy_addr %2 to [init] %0
647+
br bb2
648+
649+
bb2:
650+
copy_addr [take] %2 to %0
651+
dealloc_stack %2
652+
%r = tuple ()
653+
return %r
654+
}

0 commit comments

Comments
 (0)