From d596037875d6cadbcd27027d0d52eff09674f822 Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Tue, 10 Feb 2026 13:48:12 -0800 Subject: [PATCH] JIT: fix liveness in throw helper blocks PR #123781 changed things so that throw helper blocks are now created just after lower. Because of this they no longer get the special liveness update for unreachable blocks. Add this update in explicitly when the blocks are created. Fixes #123929 --- src/coreclr/jit/compiler.h | 1 + src/coreclr/jit/flowgraph.cpp | 4 ++++ src/coreclr/jit/liveness.cpp | 45 ++++++++++++++++++++++------------- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index c44692252ff971..5f164bf34c782b 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -6792,6 +6792,7 @@ class Compiler AddCodeDsc* fgGetExcptnTarget(SpecialCodeKind kind, BasicBlock* fromBlock, bool createIfNeeded = false); bool fgUseThrowHelperBlocks(); void fgCreateThrowHelperBlockCode(AddCodeDsc* add); + void fgSetThrowHelpBlockLiveness(BasicBlock* block); void fgSequenceLocals(Statement* stmt); private: diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp index f6fca0009125cb..f6c683b873a328 100644 --- a/src/coreclr/jit/flowgraph.cpp +++ b/src/coreclr/jit/flowgraph.cpp @@ -3492,6 +3492,10 @@ void Compiler::fgCreateThrowHelperBlock(AddCodeDsc* add) // add->acdDstBlk = newBlk; + // Set up liveness + // + fgSetThrowHelpBlockLiveness(newBlk); + #ifdef DEBUG if (verbose) { diff --git a/src/coreclr/jit/liveness.cpp b/src/coreclr/jit/liveness.cpp index c07ced43d5af4b..a3442d7cb9389e 100644 --- a/src/coreclr/jit/liveness.cpp +++ b/src/coreclr/jit/liveness.cpp @@ -1472,22 +1472,7 @@ void Liveness::DoLiveVarAnalysis() continue; } - VarSetOps::ClearD(m_compiler, block->bbLiveOut); - if (keepAliveThis) - { - unsigned thisVarIndex = m_compiler->lvaGetDesc(m_compiler->info.compThisArg)->lvVarIndex; - VarSetOps::AddElemD(m_compiler, block->bbLiveOut, thisVarIndex); - } - - if (block->HasPotentialEHSuccs(m_compiler)) - { - block->VisitEHSuccs(m_compiler, [=](BasicBlock* succ) { - VarSetOps::UnionD(m_compiler, block->bbLiveOut, succ->bbLiveIn); - return BasicBlockVisit::Continue; - }); - } - - VarSetOps::Assign(m_compiler, block->bbLiveIn, block->bbLiveOut); + m_compiler->fgSetThrowHelpBlockLiveness(block); } } @@ -1615,6 +1600,34 @@ void Compiler::fgAddHandlerLiveVars(BasicBlock* block, VARSET_TP& ehHandlerLiveV }); } +//------------------------------------------------------------------------ +// fgSetThrowHelpBlockLiveness: set liveness for throw helper block +// +// Arguments: +// block -- potential throw helper block +// +void Compiler::fgSetThrowHelpBlockLiveness(BasicBlock* block) +{ + VarSetOps::ClearD(this, block->bbLiveOut); + + const bool keepAliveThis = lvaKeepAliveAndReportThis() && lvaTable[info.compThisArg].lvTracked; + if (keepAliveThis) + { + unsigned thisVarIndex = lvaGetDesc(info.compThisArg)->lvVarIndex; + VarSetOps::AddElemD(this, block->bbLiveOut, thisVarIndex); + } + + if (block->HasPotentialEHSuccs(this)) + { + block->VisitEHSuccs(this, [=](BasicBlock* succ) { + VarSetOps::UnionD(this, block->bbLiveOut, succ->bbLiveIn); + return BasicBlockVisit::Continue; + }); + } + + VarSetOps::Assign(this, block->bbLiveIn, block->bbLiveOut); +} + #ifdef DEBUG void Compiler::fgDispBBLiveness()