Skip to content

Commit 3c65ed8

Browse files
authored
Merge pull request swiftlang#62939 from atrick/fix-live-multidef-deadend
Fix MultiDefPrunedLiveness; add boundaries for dead end blocks.
2 parents 64e65c9 + 208bb76 commit 3c65ed8

File tree

2 files changed

+44
-7
lines changed

2 files changed

+44
-7
lines changed

lib/SIL/Utils/PrunedLiveness.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,11 @@ void MultiDefPrunedLiveness::findBoundariesInBlock(
578578
boundary.deadDefs.push_back(deadArg);
579579
}
580580
}
581+
if (auto *predBB = block->getSinglePredecessorBlock()) {
582+
if (getBlockLiveness(predBB) == PrunedLiveBlocks::LiveOut) {
583+
boundary.boundaryEdges.push_back(block);
584+
}
585+
}
581586
}
582587
// All live-within blocks must contain a boundary.
583588
assert(isLiveOut

test/SILOptimizer/ossa_lifetime_analysis.sil

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,9 @@ bb0(%0 : @guaranteed $D):
176176
return %99 : $()
177177
}
178178

179-
// CHECK-LABEL: @testMultiDef
179+
// A LiveOut block with a non-SSA def, bb0, has no liveness boundary.
180+
//
181+
// CHECK-LABEL: @testMultiDefLiveOutNoBoundary
180182
// CHECK: MultiDef lifetime analysis:
181183
// CHECK: def: [[CP0:%.*]] = copy_value %0 : $C
182184
// CHECK: def: %{{.*}} = copy_value %0 : $C
@@ -187,12 +189,12 @@ bb0(%0 : @guaranteed $D):
187189
// CHECK: bb3: LiveWithin,
188190
// CHECK: bb4: LiveWithin,
189191
// CHECK: bb1: LiveWithin,
190-
// CHECK: lifetime-ending user: %{{.*}} = move_value [[CP0]] : $C
191-
// CHECK: lifetime-ending user: destroy_value [[CP0]] : $C
192-
// CHECK: lifetime-ending user: br bb4(%5 : $C)
193-
// CHECK: lifetime-ending user: br bb4(%7 : $C)
194-
// CHECK: lifetime-ending user: destroy_value %9 : $C
195-
sil [ossa] @testMultiDef : $@convention(thin) (@guaranteed C) -> () {
192+
// CHECK: last user: br bb4
193+
// CHECK-NEXT: last user: br bb4
194+
// CHECK-NEXT: last user: %{{.*}} = move_value [[CP0]] : $C
195+
// CHECK-NEXT: last user: destroy_value %{{.*}} : $C
196+
// CHECK-NEXT: last user: destroy_value [[CP0]] : $C
197+
sil [ossa] @testMultiDefLiveOutNoBoundary : $@convention(thin) (@guaranteed C) -> () {
196198
bb0(%0 : @guaranteed $C):
197199
%copy0 = copy_value %0 : $C
198200
debug_value [trace] %copy0 : $C
@@ -218,3 +220,33 @@ bb4(%phi : @owned $C):
218220
%99 = tuple()
219221
return %99 : $()
220222
}
223+
224+
// A dead-end block with a def can still be a boundary edge. This can
225+
// only happen in OSSA with incomplete lifetimes.
226+
//
227+
// CHECK-LABEL: @testMultiDefDeadDefBoundaryEdge
228+
// CHECK: MultiDef lifetime analysis:
229+
// CHECK: def: [[CP0:%.*]] = copy_value %0 : $C
230+
// CHECK: def: [[CP3:%.*]] = copy_value %0 : $C
231+
// CHECK: bb0: LiveOut,
232+
// CHECK: bb1: LiveWithin,
233+
// CHECK: bb2: LiveWithin,
234+
// CHECK: last user: destroy_value [[CP0]] : $C
235+
// CHECK-NEXT: boundary edge: bb1
236+
// CHECK-NEXT: dead def: [[CP3]] = copy_value %0 : $C
237+
sil [ossa] @testMultiDefDeadDefBoundaryEdge : $@convention(thin) (@guaranteed C) -> () {
238+
bb0(%0 : @guaranteed $C):
239+
%copy0 = copy_value %0 : $C
240+
debug_value [trace] %copy0 : $C
241+
cond_br undef, bb1, bb3
242+
243+
bb1:
244+
%dead = copy_value %0 : $C
245+
debug_value [trace] %dead : $C
246+
unreachable
247+
248+
bb3:
249+
destroy_value %copy0 : $C
250+
%99 = tuple()
251+
return %99 : $()
252+
}

0 commit comments

Comments
 (0)