Skip to content

Commit 72a243b

Browse files
authored
JIT: fix loop cloning when loop's last block is within a hander (#111432)
In some unusual cases the last block of a loop might be in the middle of a handler region (say the loop backedge is in a catch, and the catch has alternate flow that exits the loop). Make sure that we properly place the slow loop preheader into the same EH regions as the fast loop preheader. Fixes #111344
1 parent 4f16361 commit 72a243b

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

src/coreclr/jit/loopcloning.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2067,8 +2067,19 @@ void Compiler::optCloneLoop(FlowGraphNaturalLoop* loop, LoopCloneContext* contex
20672067
// bottomRedirBlk [BBJ_ALWAYS --> bottomNext]
20682068
// ... slow cloned loop (not yet inserted)
20692069
// bottomNext
2070-
BasicBlock* bottom = loop->GetLexicallyBottomMostBlock();
2071-
BasicBlock* newPred = bottom;
2070+
BasicBlock* bottom = loop->GetLexicallyBottomMostBlock();
2071+
BasicBlock* beforeSlowPreheader = bottom;
2072+
2073+
// Ensure the slow loop preheader ends up in the same EH region
2074+
// as the preheader.
2075+
//
2076+
bool inTry = false;
2077+
unsigned const enclosingRegion = ehGetMostNestedRegionIndex(preheader, &inTry);
2078+
if (!BasicBlock::sameEHRegion(beforeSlowPreheader, preheader))
2079+
{
2080+
beforeSlowPreheader = fgFindInsertPoint(enclosingRegion, inTry, bottom, /* endBlk */ nullptr,
2081+
/* nearBlk */ bottom, /* jumpBlk */ nullptr, /* runRarely */ false);
2082+
}
20722083

20732084
// Create a new preheader for the slow loop immediately before the slow
20742085
// loop itself. All failed conditions will branch to the slow preheader.
@@ -2078,22 +2089,20 @@ void Compiler::optCloneLoop(FlowGraphNaturalLoop* loop, LoopCloneContext* contex
20782089
// The slow preheader needs to go in the same EH region as the preheader.
20792090
//
20802091
JITDUMP("Create unique preheader for slow path loop\n");
2081-
const bool extendRegion = BasicBlock::sameEHRegion(bottom, preheader);
2082-
BasicBlock* slowPreheader = fgNewBBafter(BBJ_ALWAYS, newPred, extendRegion);
2083-
JITDUMP("Adding " FMT_BB " after " FMT_BB "\n", slowPreheader->bbNum, newPred->bbNum);
2084-
slowPreheader->bbWeight = newPred->isRunRarely() ? BB_ZERO_WEIGHT : ambientWeight;
2085-
slowPreheader->CopyFlags(newPred, (BBF_PROF_WEIGHT | BBF_RUN_RARELY));
2092+
const bool extendRegion = BasicBlock::sameEHRegion(beforeSlowPreheader, preheader);
2093+
BasicBlock* slowPreheader = fgNewBBafter(BBJ_ALWAYS, beforeSlowPreheader, extendRegion);
2094+
JITDUMP("Adding " FMT_BB " after " FMT_BB "\n", slowPreheader->bbNum, beforeSlowPreheader->bbNum);
2095+
slowPreheader->bbWeight = preheader->isRunRarely() ? BB_ZERO_WEIGHT : ambientWeight;
2096+
slowPreheader->CopyFlags(preheader, (BBF_PROF_WEIGHT | BBF_RUN_RARELY));
20862097
slowPreheader->scaleBBWeight(LoopCloneContext::slowPathWeightScaleFactor);
20872098

2088-
// If we didn't extend the region above (because the last loop
2099+
// If we didn't extend the region above (because the beforeSlowPreheader
20892100
// block was in some enclosed EH region), put the slow preheader
20902101
// into the appropriate region, and make appropriate extent updates.
20912102
//
20922103
if (!extendRegion)
20932104
{
20942105
slowPreheader->copyEHRegion(preheader);
2095-
bool isTry = false;
2096-
unsigned enclosingRegion = ehGetMostNestedRegionIndex(slowPreheader, &isTry);
20972106

20982107
if (enclosingRegion != 0)
20992108
{
@@ -2111,11 +2120,11 @@ void Compiler::optCloneLoop(FlowGraphNaturalLoop* loop, LoopCloneContext* contex
21112120
}
21122121
}
21132122
}
2114-
newPred = slowPreheader;
21152123

21162124
// Now we'll clone the blocks of the loop body. These cloned blocks will be the slow path.
2117-
2125+
//
21182126
BlockToBlockMap* blockMap = new (getAllocator(CMK_LoopClone)) BlockToBlockMap(getAllocator(CMK_LoopClone));
2127+
BasicBlock* newPred = slowPreheader;
21192128

21202129
if (cloneLoopsWithEH)
21212130
{

0 commit comments

Comments
 (0)