Skip to content

Commit 58695b5

Browse files
committed
[Mem2Reg] Maintain write-only lexical lifetimes.
Previously, Mem2Reg would delete write-only alloc_stacks. That is incorrect for lexical alloc_stacks--if a var was assigned but never read, we still want to keep it alive for the duration of that var's lexical scope.
1 parent 8710882 commit 58695b5

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

lib/SILOptimizer/Transforms/SILMem2Reg.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1677,7 +1677,7 @@ bool MemoryToRegisters::promoteSingleAllocation(AllocStackInst *alloc) {
16771677
}
16781678

16791679
// Remove write-only AllocStacks.
1680-
if (isWriteOnlyAllocation(alloc)) {
1680+
if (isWriteOnlyAllocation(alloc) && !shouldAddLexicalLifetime(alloc)) {
16811681
deleter.forceDeleteWithUsers(alloc);
16821682

16831683
LLVM_DEBUG(llvm::dbgs() << "*** Deleting store-only AllocStack: "<< *alloc);

test/SILOptimizer/mem2reg_lifetime.sil

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,6 +1493,37 @@ work:
14931493
unreachable
14941494
}
14951495

1496+
// CHECK-LABEL: sil [ossa] @unreachable_2 : $@convention(thin) (@owned C) -> () {
1497+
// CHECK: {{bb[^,]+}}([[INSTANCE:%[^,]+]] : @owned $C):
1498+
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[INSTANCE]]
1499+
// CHECK: [[LIFETIME_OWNED:%[^,]+]] = copy_value [[LIFETIME]]
1500+
// CHECK: end_borrow [[LIFETIME]]
1501+
// CHECK: destroy_value [[INSTANCE]]
1502+
// CHECK: unreachable
1503+
// CHECK-LABEL: } // end sil function 'unreachable_2'
1504+
sil [ossa] @unreachable_2 : $@convention(thin) (@owned C) -> () {
1505+
entry(%instance : @owned $C):
1506+
%addr = alloc_stack [lexical] $C
1507+
store %instance to [init] %addr : $*C
1508+
unreachable
1509+
}
1510+
1511+
// CHECK-LABEL: sil [ossa] @unreachable_3 : $@convention(thin) (@owned C) -> () {
1512+
// CHECK: {{bb[^,]+}}([[INSTANCE:%[^,]+]] : @owned $C):
1513+
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [lexical] [[INSTANCE]]
1514+
// CHECK: [[LIFETIME_OWNED:%[^,]+]] = copy_value [[LIFETIME]]
1515+
// CHECK: end_borrow [[LIFETIME]]
1516+
// CHECK: destroy_value [[INSTANCE]]
1517+
// CHECK: unreachable
1518+
// CHECK-LABEL: } // end sil function 'unreachable_3'
1519+
sil [ossa] @unreachable_3 : $@convention(thin) (@owned C) -> () {
1520+
entry(%instance : @owned $C):
1521+
%addr = alloc_stack [lexical] $C
1522+
store %instance to [init] %addr : $*C
1523+
%instance_loaded = load [take] %addr : $*C
1524+
unreachable
1525+
}
1526+
14961527
// CHECK-LABEL: sil [ossa] @unreachable_4 : $@convention(thin) (@owned C) -> () {
14971528
// CHECK: {{bb[^,]+}}([[INSTANCE:%[^,]+]] : @owned $C):
14981529
// CHECK: [[LIFETIME_1:%[^,]+]] = begin_borrow [lexical] [[INSTANCE]] : $C

0 commit comments

Comments
 (0)