Skip to content

Commit 05459a3

Browse files
committed
Merge pull request #2254 from eeckstein/vla-fix
ValueLifetimeAnalysis: fix the case if the last use of the value is a terminator instruction
2 parents 01fb8cf + c52b933 commit 05459a3

File tree

2 files changed

+58
-3
lines changed

2 files changed

+58
-3
lines changed

lib/SILOptimizer/Utils/Local.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,9 +1158,16 @@ bool ValueLifetimeAnalysis::computeFrontier(Frontier &Fr, Mode mode) {
11581158
// The value is not live in any of the successor blocks. This means the
11591159
// block contains a last use of the value. The next instruction after
11601160
// the last use is part of the frontier.
1161-
SILBasicBlock::iterator Iter(findLastUserInBlock(BB));
1162-
Fr.push_back(&*next(Iter));
1163-
} else if (DeadInSucc && mode != IgnoreExitEdges) {
1161+
SILInstruction *LastUser = findLastUserInBlock(BB);
1162+
if (!isa<TermInst>(LastUser)) {
1163+
Fr.push_back(&*next(LastUser->getIterator()));
1164+
continue;
1165+
}
1166+
// In case the last user is a TermInst we add all successor blocks to the
1167+
// frontier (see below).
1168+
assert(DeadInSucc && "The final using TermInst must have successors");
1169+
}
1170+
if (DeadInSucc && mode != IgnoreExitEdges) {
11641171
// The value is not live in some of the successor blocks.
11651172
LiveOutBlocks.insert(BB);
11661173
for (const SILSuccessor &Succ : BB->getSuccessors()) {

test/SILOptimizer/closure_specialize.sil

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,15 @@ bb0(%0 : $@callee_owned (@owned A) -> ()):
174174
return %3 : $()
175175
}
176176

177+
// CHECK-LABEL: sil shared {{.*}} @_TTS{{.*}}use_closure_throw : $@convention(thin) (@owned A) -> @error ErrorProtocol {
178+
sil hidden [noinline] @use_closure_throw : $@convention(thin) (@owned @callee_owned (@owned A) -> ()) -> @error ErrorProtocol {
179+
bb0(%0 : $@callee_owned (@owned A) -> ()):
180+
%1 = alloc_ref $A
181+
%2 = apply %0(%1) : $@callee_owned (@owned A) -> ()
182+
%3 = tuple ()
183+
return %3 : $()
184+
}
185+
177186
// CHECK-LABEL: sil {{.*}} @different_execution_counts
178187
// CHECK: bb0([[ARG:%.*]] : $A
179188
// CHECK: strong_retain [[ARG]]
@@ -373,6 +382,45 @@ bb3:
373382
return %11 : $()
374383
}
375384

385+
// CHECK-LABEL: sil @insert_release_after_try_apply
386+
// CHECK: bb0(%0 : $A):
387+
// CHECK: retain_value %0
388+
// CHECK: bb1:
389+
// CHECK: retain_value %0
390+
// CHECK-NEXT: try_apply
391+
// CHECK: bb2(%{{[0-9]+}} : $()):
392+
// CHECK-NEXT: strong_release %0
393+
// CHECK-NEXT: release_value %0
394+
// CHECK-NEXT: br bb4
395+
// CHECK: bb3(%{{[0-9]+}} : $ErrorProtocol):
396+
// CHECK-NEXT: strong_release %0
397+
// CHECK-NEXT: release_value %0
398+
// CHECK-NEXT: br bb4
399+
// CHECK: bb4:
400+
// CHECK-NOT: %0
401+
// CHECK: return
402+
sil @insert_release_after_try_apply : $@convention(thin) (@guaranteed A) -> () {
403+
bb0(%0 : $A):
404+
%2 = function_ref @closure : $@convention(thin) (@owned A, @owned A) -> ()
405+
%3 = partial_apply %2(%0) : $@convention(thin) (@owned A, @owned A) -> ()
406+
%8 = function_ref @use_closure_throw : $@convention(thin) (@owned @callee_owned (@owned A) -> ()) -> @error ErrorProtocol
407+
br bb1
408+
409+
bb1:
410+
strong_retain %3 : $@callee_owned (@owned A) -> ()
411+
try_apply %8(%3) : $@convention(thin) (@owned @callee_owned (@owned A) -> ()) -> @error ErrorProtocol, normal bb2, error bb3
412+
413+
bb2(%n : $()):
414+
br bb4
415+
416+
bb3(%e : $ErrorProtocol):
417+
br bb4
418+
419+
bb4:
420+
%11 = tuple ()
421+
return %11 : $()
422+
}
423+
376424

377425
// Ensure that we can specialize and properly mangle functions that take closures with @box arguments.
378426

0 commit comments

Comments
 (0)