Fix mem2reg for load_borrows with reborrows

StackAllocationPromoter::pruneAllocStackUsage substitutes loads/stores of alloc_stack
with values. For some reason isLoadFromStack was bailing out for load_borrows with
reborrows leaving them to be fixed up by fixBranchesAndUses which uses live in value
from predecessors for substitution which is obviosly incorrect the block containing
the load_borrow has a store before it.

Fixes rdar://145834542
This commit is contained in:
Meghana Gupta
2025-03-04 10:18:00 -08:00
parent f6924ee4fd
commit 4c46faad26
2 changed files with 27 additions and 5 deletions

View File

@@ -377,11 +377,6 @@ static bool isLoadFromStack(SILInstruction *i, AllocStackInst *asi) {
if (!isa<LoadInst>(i) && !isa<LoadBorrowInst>(i))
return false;
if (auto *lbi = dyn_cast<LoadBorrowInst>(i)) {
if (BorrowedValue(lbi).hasReborrow())
return false;
}
// Skip struct and tuple address projections.
ValueBase *op = i->getOperand(0);
while (op != asi) {

View File

@@ -408,3 +408,30 @@ bb6:
%17 = tuple ()
return %17 : $()
}
// CHECK-LABEL: sil [ossa] @test_load_borrow_with_reborrow :
// CHECK-NOT: alloc_stack
// CHECK-LABEL: } // end sil function 'test_load_borrow_with_reborrow'
sil [ossa] @test_load_borrow_with_reborrow : $@convention(thin) () -> () {
bb0:
%owned = apply undef() : $@convention(thin) () -> (@owned Klass)
%stack = alloc_stack [lexical] $Klass
store %owned to [init] %stack : $*Klass
br bb1
bb1:
%ld = load [take] %stack : $*Klass
destroy_value %ld
%owned_other = apply undef() : $@convention(thin) () -> (@owned Klass)
store %owned_other to [init] %stack : $*Klass
%lb = load_borrow %stack
br bb2(%lb)
bb2(%reborrow : @reborrow $Klass):
end_borrow %reborrow : $Klass
destroy_addr %stack : $*Klass
dealloc_stack %stack : $*Klass
%retval = tuple ()
return %retval : $()
}