From 22cdd73d1a56aced8578983bb41e16468320ae46 Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Mon, 2 Mar 2026 21:14:26 +0100 Subject: [PATCH 1/9] * change how flowgraph is updated --- src/coreclr/jit/ifconversion.cpp | 34 +++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index 0acda646e0d9e6..af50e498f71640 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -763,11 +763,35 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) IfConvertJoinStmts(m_elseOperation.block); } - // Update the flow from the original block. - FlowEdge* const removedEdge = m_compiler->fgRemoveAllRefPreds(m_startBlock->GetFalseTarget(), m_startBlock); - FlowEdge* const retainedEdge = m_startBlock->GetTrueEdge(); - m_startBlock->SetKindAndTargetEdge(BBJ_ALWAYS, retainedEdge); - m_compiler->fgRepairProfileCondToUncond(m_startBlock, retainedEdge, removedEdge); + // Update the flow graph. JTRUE block now contains the SELECT. + // + + // Remove flow into then/else blocks and update their weights + auto RemoveFlowInto = [&](BasicBlock* block) + { + m_compiler->fgRemoveAllRefPreds(block, m_startBlock); + block->setBBProfileWeight(0.0); + assert(block->bbPreds == nullptr); + }; + RemoveFlowInto(m_startBlock->GetFalseTarget()); + if (m_doElseConversion) + { + RemoveFlowInto(m_startBlock->GetTrueTarget()); + } + + // Change kind of JTRUE block and make it flow + // directly into block where flow merges (which is null in case of GT_RETURN) + if (m_mainOper == GT_RETURN) + { + m_startBlock->SetKindAndTargetEdge(BBJ_RETURN); + } + else + { + FlowEdge* newEdge = m_doElseConversion ? m_compiler->fgAddRefPred(m_finalBlock, m_startBlock) : m_startBlock->GetTrueEdge(); + m_startBlock->SetKindAndTargetEdge(BBJ_ALWAYS, newEdge); + } + + assert(m_startBlock->GetUniqueSucc() == m_finalBlock); #ifdef DEBUG if (m_compiler->verbose) From 54ae2c9abf593273847632b0a4bbdb296bbf9e4c Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Mon, 2 Mar 2026 22:16:00 +0100 Subject: [PATCH 2/9] * adjust Dump() to not throw * format --- src/coreclr/jit/ifconversion.cpp | 39 ++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index af50e498f71640..9bb11635159349 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -384,21 +384,32 @@ void OptIfConversionDsc::IfConvertJoinStmts(BasicBlock* fromBlock) #ifdef DEBUG void OptIfConversionDsc::IfConvertDump() { - assert(m_startBlock != nullptr); m_compiler->fgDumpBlock(m_startBlock); - BasicBlock* dumpBlock = m_startBlock->KindIs(BBJ_COND) ? m_startBlock->GetFalseTarget() : m_startBlock->GetTarget(); - for (; dumpBlock != m_finalBlock; dumpBlock = dumpBlock->GetUniqueSucc()) - { - m_compiler->fgDumpBlock(dumpBlock); - } - if (m_doElseConversion) + + bool beforeTransformation = m_startBlock->KindIs(BBJ_COND); + if (beforeTransformation) { - dumpBlock = m_startBlock->KindIs(BBJ_COND) ? m_startBlock->GetTrueTarget() : m_startBlock->GetTarget(); - for (; dumpBlock != m_finalBlock; dumpBlock = dumpBlock->GetUniqueSucc()) + // Dump all then blocks + for (BasicBlock* bb = m_startBlock->GetFalseTarget(); bb != m_finalBlock; bb = bb->GetUniqueSucc()) { - m_compiler->fgDumpBlock(dumpBlock); + m_compiler->fgDumpBlock(bb); + } + + if (m_doElseConversion) + { + // Dump all else blocks + for (BasicBlock* bb = m_startBlock->GetTrueTarget(); bb != m_finalBlock; bb = bb->GetUniqueSucc()) + { + m_compiler->fgDumpBlock(bb); + } } } + else if (m_finalBlock != nullptr) + { + // After the transformating then/else blocks are empty. Instead, + // print unique succ of the SELECT block (prev. JTRUE) where flows would merge + m_compiler->fgDumpBlock(m_finalBlock); + } } #endif @@ -767,8 +778,7 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) // // Remove flow into then/else blocks and update their weights - auto RemoveFlowInto = [&](BasicBlock* block) - { + auto RemoveFlowInto = [&](BasicBlock* block) { m_compiler->fgRemoveAllRefPreds(block, m_startBlock); block->setBBProfileWeight(0.0); assert(block->bbPreds == nullptr); @@ -779,7 +789,7 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) RemoveFlowInto(m_startBlock->GetTrueTarget()); } - // Change kind of JTRUE block and make it flow + // Change kind of JTRUE block and make it flow // directly into block where flow merges (which is null in case of GT_RETURN) if (m_mainOper == GT_RETURN) { @@ -787,7 +797,8 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) } else { - FlowEdge* newEdge = m_doElseConversion ? m_compiler->fgAddRefPred(m_finalBlock, m_startBlock) : m_startBlock->GetTrueEdge(); + FlowEdge* newEdge = + m_doElseConversion ? m_compiler->fgAddRefPred(m_finalBlock, m_startBlock) : m_startBlock->GetTrueEdge(); m_startBlock->SetKindAndTargetEdge(BBJ_ALWAYS, newEdge); } From a00736dbabd4386300ef8a9cd61970d4397d842f Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Wed, 4 Mar 2026 20:34:47 +0100 Subject: [PATCH 3/9] * bbWeight instead of setBBProfileWeight * update comments --- src/coreclr/jit/ifconversion.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index 9bb11635159349..b554ab4c826409 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -389,7 +389,7 @@ void OptIfConversionDsc::IfConvertDump() bool beforeTransformation = m_startBlock->KindIs(BBJ_COND); if (beforeTransformation) { - // Dump all then blocks + // Dump all Then blocks for (BasicBlock* bb = m_startBlock->GetFalseTarget(); bb != m_finalBlock; bb = bb->GetUniqueSucc()) { m_compiler->fgDumpBlock(bb); @@ -397,7 +397,7 @@ void OptIfConversionDsc::IfConvertDump() if (m_doElseConversion) { - // Dump all else blocks + // Dump all Else blocks for (BasicBlock* bb = m_startBlock->GetTrueTarget(); bb != m_finalBlock; bb = bb->GetUniqueSucc()) { m_compiler->fgDumpBlock(bb); @@ -406,8 +406,8 @@ void OptIfConversionDsc::IfConvertDump() } else if (m_finalBlock != nullptr) { - // After the transformating then/else blocks are empty. Instead, - // print unique succ of the SELECT block (prev. JTRUE) where flows would merge + // After the transformation Then/Else blocks are empty. Instead, + // dump unique successor of the SELECT (previously JTRUE) block where flows merge m_compiler->fgDumpBlock(m_finalBlock); } } @@ -777,10 +777,10 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) // Update the flow graph. JTRUE block now contains the SELECT. // - // Remove flow into then/else blocks and update their weights + // Remove flow into Then/Else blocks and update their weights auto RemoveFlowInto = [&](BasicBlock* block) { m_compiler->fgRemoveAllRefPreds(block, m_startBlock); - block->setBBProfileWeight(0.0); + block->bbWeight = 0.0; assert(block->bbPreds == nullptr); }; RemoveFlowInto(m_startBlock->GetFalseTarget()); @@ -790,7 +790,7 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) } // Change kind of JTRUE block and make it flow - // directly into block where flow merges (which is null in case of GT_RETURN) + // directly into block where flows merge (which is null in case of GT_RETURN) if (m_mainOper == GT_RETURN) { m_startBlock->SetKindAndTargetEdge(BBJ_RETURN); From 9d639fbb0f7bf441abc73ea4330da27eed9496eb Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Fri, 6 Mar 2026 00:07:00 +0100 Subject: [PATCH 4/9] * use BB_ZERO_WEIGHT * don't dump m_finalBlock --- src/coreclr/jit/ifconversion.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index b554ab4c826409..7c28be1edc4d4e 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -404,12 +404,6 @@ void OptIfConversionDsc::IfConvertDump() } } } - else if (m_finalBlock != nullptr) - { - // After the transformation Then/Else blocks are empty. Instead, - // dump unique successor of the SELECT (previously JTRUE) block where flows merge - m_compiler->fgDumpBlock(m_finalBlock); - } } #endif @@ -780,7 +774,7 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) // Remove flow into Then/Else blocks and update their weights auto RemoveFlowInto = [&](BasicBlock* block) { m_compiler->fgRemoveAllRefPreds(block, m_startBlock); - block->bbWeight = 0.0; + block->bbWeight = BB_ZERO_WEIGHT; assert(block->bbPreds == nullptr); }; RemoveFlowInto(m_startBlock->GetFalseTarget()); From 3e282c79dae91c6a32c3d8967ae1d02f3b2cd65f Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Sat, 7 Mar 2026 06:53:11 +0100 Subject: [PATCH 5/9] * remove Then/Else blocks --- src/coreclr/jit/ifconversion.cpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index 41d495a930ee6b..0f23121853b600 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -771,16 +771,26 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) // Update the flow graph. JTRUE block now contains the SELECT. // - // Remove flow into Then/Else blocks and update their weights - auto RemoveFlowInto = [&](BasicBlock* block) { - m_compiler->fgRemoveAllRefPreds(block, m_startBlock); - block->bbWeight = BB_ZERO_WEIGHT; - assert(block->bbPreds == nullptr); + BasicBlock* falseBb = m_startBlock->GetFalseTarget(); + BasicBlock* trueBb = m_startBlock->GetTrueTarget(); + + // Remove all Then/Else blocks + auto removeBlocks = [&](BasicBlock* start) { + m_compiler->fgRemoveAllRefPreds(start, m_startBlock); + start->bbWeight = BB_ZERO_WEIGHT; + assert(start->bbPreds == nullptr); + + for (BasicBlock* bb = start; bb != m_finalBlock;) + { + BasicBlock* next = bb->GetUniqueSucc(); + m_compiler->fgRemoveBlock(bb, true); + bb = next; + } }; - RemoveFlowInto(m_startBlock->GetFalseTarget()); + removeBlocks(falseBb); if (m_doElseConversion) { - RemoveFlowInto(m_startBlock->GetTrueTarget()); + removeBlocks(trueBb); } // Change kind of JTRUE block and make it flow @@ -795,7 +805,6 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) m_doElseConversion ? m_compiler->fgAddRefPred(m_finalBlock, m_startBlock) : m_startBlock->GetTrueEdge(); m_startBlock->SetKindAndTargetEdge(BBJ_ALWAYS, newEdge); } - assert(m_startBlock->GetUniqueSucc() == m_finalBlock); #ifdef DEBUG From 4cdf2a49ce176e51d2d94b43f5a252a5900e6312 Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Sat, 7 Mar 2026 06:55:54 +0100 Subject: [PATCH 6/9] * fix order --- src/coreclr/jit/ifconversion.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index 0f23121853b600..ff6a3fcd0b5b41 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -774,6 +774,20 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) BasicBlock* falseBb = m_startBlock->GetFalseTarget(); BasicBlock* trueBb = m_startBlock->GetTrueTarget(); + // Change kind of JTRUE block and make it flow + // directly into block where flows merge (which is null in case of GT_RETURN) + if (m_mainOper == GT_RETURN) + { + m_startBlock->SetKindAndTargetEdge(BBJ_RETURN); + } + else + { + FlowEdge* newEdge = + m_doElseConversion ? m_compiler->fgAddRefPred(m_finalBlock, m_startBlock) : m_startBlock->GetTrueEdge(); + m_startBlock->SetKindAndTargetEdge(BBJ_ALWAYS, newEdge); + } + assert(m_startBlock->GetUniqueSucc() == m_finalBlock); + // Remove all Then/Else blocks auto removeBlocks = [&](BasicBlock* start) { m_compiler->fgRemoveAllRefPreds(start, m_startBlock); @@ -793,20 +807,6 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) removeBlocks(trueBb); } - // Change kind of JTRUE block and make it flow - // directly into block where flows merge (which is null in case of GT_RETURN) - if (m_mainOper == GT_RETURN) - { - m_startBlock->SetKindAndTargetEdge(BBJ_RETURN); - } - else - { - FlowEdge* newEdge = - m_doElseConversion ? m_compiler->fgAddRefPred(m_finalBlock, m_startBlock) : m_startBlock->GetTrueEdge(); - m_startBlock->SetKindAndTargetEdge(BBJ_ALWAYS, newEdge); - } - assert(m_startBlock->GetUniqueSucc() == m_finalBlock); - #ifdef DEBUG if (m_compiler->verbose) { From 8f3e02fae399491d3f27bad974fd0c6ebb3c2332 Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Sun, 8 Mar 2026 00:10:56 +0100 Subject: [PATCH 7/9] * remove NOP after SELECT --- src/coreclr/jit/ifconversion.cpp | 64 ++++++++++---------------------- 1 file changed, 20 insertions(+), 44 deletions(-) diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index ff6a3fcd0b5b41..b4da1140cf05c0 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -55,7 +55,6 @@ class OptIfConversionDsc bool IfConvertCheckThenFlow(); void IfConvertFindFlow(); bool IfConvertCheckStmts(BasicBlock* fromBlock, IfConvertOperation* foundOperation); - void IfConvertJoinStmts(BasicBlock* fromBlock); GenTree* TryTransformSelectOperOrLocal(GenTree* oper, GenTree* lcl); GenTree* TryTransformSelectOperOrZero(GenTree* oper, GenTree* lcl); @@ -356,26 +355,6 @@ bool OptIfConversionDsc::IfConvertCheckStmts(BasicBlock* fromBlock, IfConvertOpe return found; } -//----------------------------------------------------------------------------- -// IfConvertJoinStmts -// -// Move all the statements from a block onto the end of the start block. -// -// Arguments: -// fromBlock -- Source block -// -void OptIfConversionDsc::IfConvertJoinStmts(BasicBlock* fromBlock) -{ - Statement* stmtList1 = m_startBlock->firstStmt(); - Statement* stmtList2 = fromBlock->firstStmt(); - Statement* stmtLast1 = m_startBlock->lastStmt(); - Statement* stmtLast2 = fromBlock->lastStmt(); - stmtLast1->SetNextStmt(stmtList2); - stmtList2->SetPrevStmt(stmtLast1); - stmtList1->SetPrevStmt(stmtLast2); - fromBlock->SetFirstStmt(nullptr); -} - //----------------------------------------------------------------------------- // IfConvertDump // @@ -736,9 +715,16 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) select = m_compiler->gtNewConditionalNode(GT_SELECT, m_cond, selectTrueInput, selectFalseInput, selectType); } - m_thenOperation.node->AddAllEffectsFlags(select); + // Update statements + // + + // Remove JTRUE statement + last->gtBashToNOP(); + m_compiler->gtSetEvalOrder(last); + m_compiler->fgSetStmtSeq(m_startBlock->lastStmt()); - // Use the select as the source of the Then operation. + // Use the SELECT as the source of the Then STORE/RETURN. + m_thenOperation.node->AddAllEffectsFlags(select); if (m_mainOper == GT_STORE_LCL_VAR) { m_thenOperation.node->AsLclVar()->Data() = select; @@ -750,32 +736,22 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) m_compiler->gtSetEvalOrder(m_thenOperation.node); m_compiler->fgSetStmtSeq(m_thenOperation.stmt); - // Remove statements. - last->gtBashToNOP(); - m_compiler->gtSetEvalOrder(last); - m_compiler->fgSetStmtSeq(m_startBlock->lastStmt()); - if (m_doElseConversion) - { - m_elseOperation.node->gtBashToNOP(); - m_compiler->gtSetEvalOrder(m_elseOperation.node); - m_compiler->fgSetStmtSeq(m_elseOperation.stmt); - } - - // Merge all the blocks. - IfConvertJoinStmts(m_thenOperation.block); - if (m_doElseConversion) - { - IfConvertJoinStmts(m_elseOperation.block); - } + // Append STORE(SELECT)/RETURN(SELECT) statement to JTRUE block + Statement* useSelectStmt = m_thenOperation.stmt; + useSelectStmt->SetNextStmt(nullptr); + useSelectStmt->SetPrevStmt(m_startBlock->lastStmt()); + m_startBlock->lastStmt()->SetNextStmt(useSelectStmt); + m_startBlock->firstStmt()->SetPrevStmt(useSelectStmt); + m_thenOperation.block->SetFirstStmt(nullptr); - // Update the flow graph. JTRUE block now contains the SELECT. + // Update flow graph. JTRUE block now contains the SELECT. // - + BasicBlock* falseBb = m_startBlock->GetFalseTarget(); BasicBlock* trueBb = m_startBlock->GetTrueTarget(); - // Change kind of JTRUE block and make it flow - // directly into block where flows merge (which is null in case of GT_RETURN) + // Change kind of JTRUE block and make it flow directly into + // block where flows merge (which is null in case of GT_RETURN) if (m_mainOper == GT_RETURN) { m_startBlock->SetKindAndTargetEdge(BBJ_RETURN); From 885f16cf8ba275e32006768eb0af168e0bfb8347 Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Sun, 8 Mar 2026 19:32:10 +0100 Subject: [PATCH 8/9] * replace JTRUE with SELECT instead of appending it --- src/coreclr/jit/ifconversion.cpp | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index b4da1140cf05c0..a5d86a2298c2ee 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -715,14 +715,6 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) select = m_compiler->gtNewConditionalNode(GT_SELECT, m_cond, selectTrueInput, selectFalseInput, selectType); } - // Update statements - // - - // Remove JTRUE statement - last->gtBashToNOP(); - m_compiler->gtSetEvalOrder(last); - m_compiler->fgSetStmtSeq(m_startBlock->lastStmt()); - // Use the SELECT as the source of the Then STORE/RETURN. m_thenOperation.node->AddAllEffectsFlags(select); if (m_mainOper == GT_STORE_LCL_VAR) @@ -736,22 +728,16 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) m_compiler->gtSetEvalOrder(m_thenOperation.node); m_compiler->fgSetStmtSeq(m_thenOperation.stmt); - // Append STORE(SELECT)/RETURN(SELECT) statement to JTRUE block - Statement* useSelectStmt = m_thenOperation.stmt; - useSelectStmt->SetNextStmt(nullptr); - useSelectStmt->SetPrevStmt(m_startBlock->lastStmt()); - m_startBlock->lastStmt()->SetNextStmt(useSelectStmt); - m_startBlock->firstStmt()->SetPrevStmt(useSelectStmt); + // Replace JTRUE with STORE(SELECT)/RETURN(SELECT) statement + m_compiler->fgRemoveStmt(m_startBlock, m_startBlock->lastStmt()); + m_compiler->fgInsertStmtAtEnd(m_startBlock, m_thenOperation.stmt); m_thenOperation.block->SetFirstStmt(nullptr); - // Update flow graph. JTRUE block now contains the SELECT. - // - BasicBlock* falseBb = m_startBlock->GetFalseTarget(); BasicBlock* trueBb = m_startBlock->GetTrueTarget(); - // Change kind of JTRUE block and make it flow directly into - // block where flows merge (which is null in case of GT_RETURN) + // JTRUE block now contains SELECT. Change it's kind and make it flow + // directly into block where flows merge, which is null in case of GT_RETURN. if (m_mainOper == GT_RETURN) { m_startBlock->SetKindAndTargetEdge(BBJ_RETURN); From e63e21a09fe427a04c2f83df3634e870222dea7e Mon Sep 17 00:00:00 2001 From: BoyBaykiller Date: Sun, 8 Mar 2026 20:50:53 +0100 Subject: [PATCH 9/9] * try fix CI 'Assertion failed 'stmt->GetNextStmt() == nullptr' --- src/coreclr/jit/ifconversion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/ifconversion.cpp b/src/coreclr/jit/ifconversion.cpp index a5d86a2298c2ee..0b9e11c962e8fb 100644 --- a/src/coreclr/jit/ifconversion.cpp +++ b/src/coreclr/jit/ifconversion.cpp @@ -729,8 +729,8 @@ bool OptIfConversionDsc::optIfConvert(int* pReachabilityBudget) m_compiler->fgSetStmtSeq(m_thenOperation.stmt); // Replace JTRUE with STORE(SELECT)/RETURN(SELECT) statement + m_compiler->fgInsertStmtBefore(m_startBlock, m_startBlock->lastStmt(), m_thenOperation.stmt); m_compiler->fgRemoveStmt(m_startBlock, m_startBlock->lastStmt()); - m_compiler->fgInsertStmtAtEnd(m_startBlock, m_thenOperation.stmt); m_thenOperation.block->SetFirstStmt(nullptr); BasicBlock* falseBb = m_startBlock->GetFalseTarget();