Skip to content

Commit 81351da

Browse files
committed
Fix creation of end_borrows of store_borrows in ForEachLoopUnroll
end_borrow should not be inserted after dealloc_stack of the destination
1 parent 4d77b82 commit 81351da

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

lib/SILOptimizer/LoopTransforms/ForEachLoopUnroll.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,7 @@ static void unrollForEach(ArrayInfo &arrayInfo, TryApplyInst *forEachCall,
538538
SILBasicBlock *currentBB = num > 1 ? normalTargetGenerator(nextNormalBB)
539539
: forEachCall->getParentBlock();
540540
SILBuilderWithScope unrollBuilder(currentBB, forEachCall);
541+
SILBuilderWithScope normalBuilder(&nextNormalBB->front(), forEachCall);
541542
SILValue borrowedElem;
542543
SILValue addr;
543544

@@ -552,9 +553,8 @@ static void unrollForEach(ArrayInfo &arrayInfo, TryApplyInst *forEachCall,
552553
borrowedElem = unrollBuilder.createBeginBorrow(forEachLoc, elementCopy);
553554
addr =
554555
unrollBuilder.createStoreBorrow(forEachLoc, borrowedElem, allocStack);
555-
SILBuilderWithScope builder(&nextNormalBB->front(), forEachCall);
556-
builder.createEndBorrow(forEachLoc, addr);
557-
builder.createEndBorrow(forEachLoc, borrowedElem);
556+
normalBuilder.createEndBorrow(forEachLoc, addr);
557+
normalBuilder.createEndBorrow(forEachLoc, borrowedElem);
558558
}
559559

560560
SILBasicBlock *errorTarget =
@@ -566,16 +566,18 @@ static void unrollForEach(ArrayInfo &arrayInfo, TryApplyInst *forEachCall,
566566
unrollBuilder.createTryApply(forEachLoc, forEachBodyClosure,
567567
SubstitutionMap(), addr, nextNormalBB,
568568
errorTarget);
569+
570+
if (nextNormalBB == normalBB) {
571+
// Dealloc the stack in the normalBB and also in errorBB. Note that every
572+
// try_apply created during the unrolling must pass through these blocks.
573+
normalBuilder.createDeallocStack(forEachLoc, allocStack);
574+
}
569575
nextNormalBB = currentBB;
570576
}
571-
572577
// Dealloc the stack in the normalBB and also in errorBB. Note that every
573578
// try_apply created during the unrolling must pass through these blocks.
574-
SILBuilderWithScope(&normalBB->front())
575-
.createDeallocStack(forEachLoc, allocStack);
576579
SILBuilderWithScope(&errorBB->front())
577580
.createDeallocStack(forEachLoc, allocStack);
578-
579581
// Remove the forEach call as it has now been unrolled.
580582
removeForEachCall(forEachCall, deleter);
581583
}

test/SILOptimizer/for_each_loop_unroll_test.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ bb2(%39 : @owned $Error):
134134
// CHECK: br [[ERROR3:bb[0-9]+]]([[ERRPARAM2]] : $any Error)
135135

136136
// CHECK: [[NORMAL2]](%{{.*}} : $()):
137-
// CHECK: dealloc_stack [[STACK]]
138137
// CHECK: end_borrow [[ELEM2BORROW]]
138+
// CHECK: dealloc_stack [[STACK]]
139139
// Note that the temporary alloc_stack of the array created for the forEach call
140140
// will be cleaned up when the forEach call is removed.
141141
// CHECK: destroy_value

0 commit comments

Comments
 (0)