diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index 435f1c0d2a41f..711066ed66fe9 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -5964,9 +5964,9 @@ bool FlowGraphNaturalLoop::CanDuplicate(INDEBUG(const char** reason)) Compiler* comp = m_dfsTree->GetCompiler(); BasicBlockVisit result = VisitLoopBlocks([=](BasicBlock* block) { - if (comp->bbIsTryBeg(block)) + if (!BasicBlock::sameEHRegion(block, GetHeader())) { - INDEBUG(*reason = "Loop has a `try` begin"); + INDEBUG(*reason = "Loop not entirely within one EH region"); return BasicBlockVisit::Abort; } diff --git a/src/coreclr/jit/loopcloning.cpp b/src/coreclr/jit/loopcloning.cpp index ee2f6077a3c50..bb968dee899d8 100644 --- a/src/coreclr/jit/loopcloning.cpp +++ b/src/coreclr/jit/loopcloning.cpp @@ -1929,7 +1929,6 @@ bool Compiler::optIsLoopClonable(FlowGraphNaturalLoop* loop, LoopCloneContext* c loop->GetIndex()); return false; } - assert(!requireIterable || !lvaVarAddrExposed(iterInfo->IterVar)); if (requireIterable) diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp index 9bbf8966de506..161478d63f0c7 100644 --- a/src/coreclr/jit/optimizer.cpp +++ b/src/coreclr/jit/optimizer.cpp @@ -2866,15 +2866,28 @@ bool Compiler::optCreatePreheader(FlowGraphNaturalLoop* loop) { BasicBlock* header = loop->GetHeader(); - // If the header is already a try entry then we need to keep it as such - // since blocks from within the loop will be jumping back to it after we're - // done. Thus, in that case we insert the preheader in the enclosing try - // region. - unsigned headerEHRegion = header->hasTryIndex() ? header->getTryIndex() : EHblkDsc::NO_ENCLOSING_INDEX; - unsigned preheaderEHRegion = headerEHRegion; - if ((headerEHRegion != EHblkDsc::NO_ENCLOSING_INDEX) && bbIsTryBeg(header)) + // If all loop backedges sources are within the same try region as the loop header, + // then the preheader can be in the same try region as the header. + // + // Otherwise the preheader must be in the enclosing try region. + // + unsigned preheaderEHRegion = EHblkDsc::NO_ENCLOSING_INDEX; + bool inSameRegionAsHeader = true; + if (header->hasTryIndex()) { - preheaderEHRegion = ehTrueEnclosingTryIndexIL(headerEHRegion); + preheaderEHRegion = header->getTryIndex(); + for (FlowEdge* backEdge : loop->BackEdges()) + { + BasicBlock* const backedgeSource = backEdge->getSourceBlock(); + if (!bbInTryRegions(preheaderEHRegion, backedgeSource)) + { + // Preheader should be in the true enclosing region of the header. + // + preheaderEHRegion = ehTrueEnclosingTryIndexIL(preheaderEHRegion); + inSameRegionAsHeader = false; + break; + } + } } if (!bbIsHandlerBeg(header) && (loop->EntryEdges().size() == 1)) @@ -2893,7 +2906,16 @@ bool Compiler::optCreatePreheader(FlowGraphNaturalLoop* loop) BasicBlock* preheader = fgNewBBbefore(BBJ_ALWAYS, header, false); preheader->SetFlags(BBF_INTERNAL); - fgSetEHRegionForNewPreheaderOrExit(preheader); + + if (inSameRegionAsHeader) + { + fgExtendEHRegionBefore(header); + } + else + { + fgSetEHRegionForNewPreheaderOrExit(preheader); + } + preheader->bbCodeOffs = header->bbCodeOffs; JITDUMP("Created new preheader " FMT_BB " for " FMT_LP "\n", preheader->bbNum, loop->GetIndex());