Skip to content

Commit e26affa

Browse files
committed
ComputeSideEffects: correct side effects for destroy_addr
A destroy_addr also involves a read from the address. It's equivalent to a `%x = load [take]` and `destroy_value %x`. It's also a write, because the stored value is not available anymore after the destroy. Fixes a compiler crash in SILMem2Reg. rdar://103879105
1 parent ce4ec08 commit e26affa

File tree

2 files changed

+13
-4
lines changed

2 files changed

+13
-4
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ComputeSideEffects.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,11 @@ private struct CollectedEffects {
9898
addDestroyEffects(of: inst.operands[0].value)
9999

100100
case let da as DestroyAddrInst:
101+
// A destroy_addr also involves a read from the address. It's equivalent to a `%x = load [take]` and `destroy_value %x`.
102+
addEffects(.read, to: da.operand)
103+
// Conceptually, it's also a write, because the stored value is not available anymore after the destroy
104+
addEffects(.write, to: da.operand)
105+
101106
addDestroyEffects(of: da.operand)
102107

103108
case let copy as CopyAddrInst:
@@ -108,12 +113,16 @@ private struct CollectedEffects {
108113
addEffects(.copy, to: copy.source)
109114
}
110115
if !copy.isInitializationOfDest {
116+
// Like for destroy_addr, the destroy also involves a read.
117+
addEffects(.read, to: copy.destination)
111118
addDestroyEffects(of: copy.destination)
112119
}
113120

114121
case let store as StoreInst:
115122
addEffects(.write, to: store.destination)
116123
if store.destinationOwnership == .assign {
124+
// Like for destroy_addr, the destroy also involves a read.
125+
addEffects(.read, to: store.destination)
117126
addDestroyEffects(of: store.destination)
118127
}
119128

test/SILOptimizer/side_effects.sil

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ bb0(%0 : @owned $SP):
436436
}
437437

438438
// CHECK-LABEL: sil [ossa] @store_destoys
439-
// CHECK-NEXT: [%0: write v**, destroy v**]
439+
// CHECK-NEXT: [%0: read v**, write v**, destroy v**]
440440
// CHECK-NEXT: [%1: write c*.v**, copy c*.v**]
441441
// CHECK-NEXT: [global: write,copy]
442442
// CHECK-NEXT: {{^[^[]}}
@@ -448,7 +448,7 @@ bb0(%0 : $*X, %1 : @owned $X):
448448
}
449449

450450
// CHECK-LABEL: sil [ossa] @unknown_destructor_effects
451-
// CHECK-NEXT: [%0: write v**, destroy v**]
451+
// CHECK-NEXT: [%0: read v**, write v**, destroy v**]
452452
// CHECK-NEXT: [%1: read c*.v**, write c*.v**, copy c*.v**, destroy c*.v**]
453453
// CHECK-NEXT: [global: read,write,copy,destroy,allocate,deinit_barrier]
454454
// CHECK-NEXT: {{^[^[]}}
@@ -471,7 +471,7 @@ bb0(%0 : $*X, %1 : @owned $X):
471471
}
472472

473473
// CHECK-LABEL: sil [ossa] @copy_destoys
474-
// CHECK-NEXT: [%0: write v**, destroy v**]
474+
// CHECK-NEXT: [%0: read v**, write v**, destroy v**]
475475
// CHECK-NEXT: [%1: read v**, copy v**]
476476
// CHECK-NEXT: [global: write,copy]
477477
// CHECK-NEXT: {{^[^[]}}
@@ -518,7 +518,7 @@ bb0(%0 : @owned $SP):
518518
}
519519

520520
// CHECK-LABEL: sil [ossa] @destroy_addr_effects
521-
// CHECK-NEXT: [%0: destroy v**]
521+
// CHECK-NEXT: [%0: read v**, write v**, destroy v**]
522522
// CHECK-NEXT: [global: write,copy]
523523
// CHECK-NEXT: {{^[^[]}}
524524
sil [ossa] @destroy_addr_effects : $@convention(thin) (@in X) -> () {

0 commit comments

Comments
 (0)