Skip to content

Commit 5a98e1a

Browse files
committed
Fix Mem2Reg to avoid creating undef as a replacement for load of an empty tuple
1 parent 4dffe27 commit 5a98e1a

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed

lib/SILOptimizer/Transforms/SILMem2Reg.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1488,7 +1488,7 @@ static bool isCaptured(AllocStackInst *asi, bool &inSingleBlock) {
14881488
for (auto *use : asi->getUses()) {
14891489
SILInstruction *user = use->getUser();
14901490

1491-
if (user->getParent() != singleBlock)
1491+
if (!isa<DeallocStackInst>(user) && user->getParent() != singleBlock)
14921492
singleBlock = nullptr;
14931493

14941494
// Loads are okay.
@@ -1763,13 +1763,17 @@ bool MemoryToRegisters::promoteSingleAllocation(AllocStackInst *alloc) {
17631763
if (alloc->use_empty()) {
17641764
deleter.forceDelete(alloc);
17651765
} else {
1766-
// Handle a corner case where the ASI still has uses:
1767-
// This can come up if the source contains a withUnsafePointer where
1768-
// the pointer escapes. It's illegal code but we should not crash.
1769-
// Re-insert a dealloc_stack so that the verifier is happy.
1770-
auto *next = alloc->getNextInstruction();
1771-
SILBuilderWithScope b(next, ctx);
1772-
b.createDeallocStack(next->getLoc(), alloc);
1766+
// Delete dealloc uses in other blocks
1767+
SmallVector<SILInstruction *, 8> deallocs;
1768+
for (auto *use : alloc->getUses()) {
1769+
auto *user = use->getUser();
1770+
assert(isa<DeallocStackInst>(user));
1771+
deallocs.push_back(user);
1772+
}
1773+
for (auto dealloc : deallocs) {
1774+
dealloc->eraseFromParent();
1775+
}
1776+
deleter.forceDelete(alloc);
17731777
}
17741778
return true;
17751779
} else {

test/SILOptimizer/mem2reg_ossa.sil

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,22 @@ bb0:
489489
return %16 : $((), ())
490490
}
491491

492+
// CHECK-LABEL: sil [ossa] @load_tuple_of_void2 :
493+
// CHECK-NOT: alloc_stack
494+
// CHECK: [[T:%[0-9]+]] = tuple ()
495+
// CHECK: return [[T]] : $()
496+
// CHECK: } // end sil function 'load_tuple_of_void2'
497+
sil [ossa] @load_tuple_of_void2 : $@convention(thin) () -> () {
498+
bb0:
499+
%1 = alloc_stack $()
500+
%16 = load [trivial] %1 : $*()
501+
br bb2
502+
503+
bb2:
504+
dealloc_stack %1 : $*()
505+
return %16 : $()
506+
}
507+
492508
// CHECK-LABEL: sil [ossa] @dont_optimize_optional_in_multiple_blocks :
493509
// CHECK: alloc_stack
494510
// CHECK: } // end sil function 'dont_optimize_optional_in_multiple_blocks'

0 commit comments

Comments
 (0)