@@ -5462,7 +5462,7 @@ int Compiler::optIsSetAssgLoop(unsigned lnum, ALLVARSET_VALARG_TP vars, varRefKi
54625462 return 0 ;
54635463}
54645464
5465- void Compiler::optPerformHoistExpr (GenTree* origExpr, unsigned lnum)
5465+ void Compiler::optPerformHoistExpr (GenTree* origExpr, BasicBlock* exprBb, unsigned lnum)
54665466{
54675467#ifdef DEBUG
54685468 if (verbose)
@@ -5476,6 +5476,8 @@ void Compiler::optPerformHoistExpr(GenTree* origExpr, unsigned lnum)
54765476 }
54775477#endif
54785478
5479+ assert (exprBb != nullptr );
5480+
54795481 // This loop has to be in a form that is approved for hoisting.
54805482 assert (optLoopTable[lnum].lpFlags & LPFLG_HOISTABLE);
54815483
@@ -5512,6 +5514,8 @@ void Compiler::optPerformHoistExpr(GenTree* origExpr, unsigned lnum)
55125514 compCurBB = preHead;
55135515 hoist = fgMorphTree (hoist);
55145516
5517+ preHead->bbFlags |= (exprBb->bbFlags & (BBF_HAS_IDX_LEN | BBF_HAS_NULLCHECK));
5518+
55155519 Statement* hoistStmt = gtNewStmt (hoist);
55165520 hoistStmt->SetCompilerAdded ();
55175521
@@ -6205,6 +6209,7 @@ void Compiler::optHoistLoopBlocks(unsigned loopNum, ArrayStack<BasicBlock*>* blo
62056209 bool m_beforeSideEffect;
62066210 unsigned m_loopNum;
62076211 LoopHoistContext* m_hoistContext;
6212+ BasicBlock* m_currentBlock;
62086213
62096214 bool IsNodeHoistable (GenTree* node)
62106215 {
@@ -6297,19 +6302,21 @@ void Compiler::optHoistLoopBlocks(unsigned loopNum, ArrayStack<BasicBlock*>* blo
62976302 , m_beforeSideEffect(true )
62986303 , m_loopNum(loopNum)
62996304 , m_hoistContext(hoistContext)
6305+ , m_currentBlock(nullptr )
63006306 {
63016307 }
63026308
63036309 void HoistBlock (BasicBlock* block)
63046310 {
6311+ m_currentBlock = block;
63056312 for (Statement* const stmt : block->NonPhiStatements ())
63066313 {
63076314 WalkTree (stmt->GetRootNodePointer (), nullptr );
63086315 assert (m_valueStack.TopRef ().Node () == stmt->GetRootNode ());
63096316
63106317 if (m_valueStack.TopRef ().m_hoistable )
63116318 {
6312- m_compiler->optHoistCandidate (stmt->GetRootNode (), m_loopNum, m_hoistContext);
6319+ m_compiler->optHoistCandidate (stmt->GetRootNode (), block, m_loopNum, m_hoistContext);
63136320 }
63146321
63156322 m_valueStack.Reset ();
@@ -6612,7 +6619,7 @@ void Compiler::optHoistLoopBlocks(unsigned loopNum, ArrayStack<BasicBlock*>* blo
66126619 value.m_hoistable = false ;
66136620 value.m_invariant = false ;
66146621
6615- m_compiler->optHoistCandidate (value.Node (), m_loopNum, m_hoistContext);
6622+ m_compiler->optHoistCandidate (value.Node (), m_currentBlock, m_loopNum, m_hoistContext);
66166623 }
66176624 }
66186625 }
@@ -6654,7 +6661,7 @@ void Compiler::optHoistLoopBlocks(unsigned loopNum, ArrayStack<BasicBlock*>* blo
66546661 }
66556662}
66566663
6657- void Compiler::optHoistCandidate (GenTree* tree, unsigned lnum, LoopHoistContext* hoistCtxt)
6664+ void Compiler::optHoistCandidate (GenTree* tree, BasicBlock* treeBb, unsigned lnum, LoopHoistContext* hoistCtxt)
66586665{
66596666 assert (lnum != BasicBlock::NOT_IN_LOOP);
66606667 assert ((optLoopTable[lnum].lpFlags & LPFLG_HOISTABLE) != 0 );
@@ -6679,7 +6686,7 @@ void Compiler::optHoistCandidate(GenTree* tree, unsigned lnum, LoopHoistContext*
66796686 }
66806687
66816688 // Expression can be hoisted
6682- optPerformHoistExpr (tree, lnum);
6689+ optPerformHoistExpr (tree, treeBb, lnum);
66836690
66846691 // Increment lpHoistedExprCount or lpHoistedFPExprCount
66856692 if (!varTypeIsFloating (tree->TypeGet ()))
0 commit comments