diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp index 387f38f7d42b09..831963edd91a35 100644 --- a/src/coreclr/jit/compiler.cpp +++ b/src/coreclr/jit/compiler.cpp @@ -4946,6 +4946,10 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl if (opts.OptimizationEnabled()) { + // Conditional to switch conversion, and switch peeling + // + DoPhase(this, PHASE_SWITCH_RECOGNITION, &Compiler::optRecognizeAndOptimizeSwitchJumps); + // Optimize boolean conditions // DoPhase(this, PHASE_OPTIMIZE_BOOLS, &Compiler::optOptimizeBools); @@ -4954,10 +4958,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl // DoPhase(this, PHASE_IF_CONVERSION, &Compiler::optIfConversion); - // Conditional to switch conversion, and switch peeling - // - DoPhase(this, PHASE_SWITCH_RECOGNITION, &Compiler::optRecognizeAndOptimizeSwitchJumps); - // Run flow optimizations before reordering blocks // DoPhase(this, PHASE_OPTIMIZE_PRE_LAYOUT, &Compiler::optOptimizePreLayout); diff --git a/src/coreclr/jit/optimizebools.cpp b/src/coreclr/jit/optimizebools.cpp index 451f35241799e2..9f5bf58809f5b3 100644 --- a/src/coreclr/jit/optimizebools.cpp +++ b/src/coreclr/jit/optimizebools.cpp @@ -1715,7 +1715,7 @@ bool Compiler::fgFoldCondToReturnBlock(BasicBlock* block) modified = true; } // Same here - bail out if the block is no longer BBJ_COND after compacting. - if (!block->KindIs(BBJ_COND)) + if (block->HasFlag(BBF_REMOVED) || !block->KindIs(BBJ_COND)) { return modified; } diff --git a/src/coreclr/jit/switchrecognition.cpp b/src/coreclr/jit/switchrecognition.cpp index 739a8eda4ab1ac..8016b5831ae402 100644 --- a/src/coreclr/jit/switchrecognition.cpp +++ b/src/coreclr/jit/switchrecognition.cpp @@ -32,6 +32,29 @@ PhaseStatus Compiler::optRecognizeAndOptimizeSwitchJumps() continue; } + // Before we start, let's optimize possible fallthrough blocks for BBJ_COND's successors. + if (block->KindIs(BBJ_COND) && block->hasSingleStmt()) + { + BasicBlock* retFalseBb = block->GetFalseTarget(); + BasicBlock* retTrueBb = block->GetTrueTarget(); + if (fgCanCompactBlock(retTrueBb) && retTrueBb->isEmpty()) + { + fgCompactBlock(retTrueBb); + modified = true; + } + // fgCompactBlock could have removed retFalseBb and the block, so we + // need to check BBF_REMOVED flag for both. + if (!retFalseBb->HasFlag(BBF_REMOVED) && fgCanCompactBlock(retFalseBb)) + { + fgCompactBlock(retFalseBb); + modified = true; + } + if (block->HasFlag(BBF_REMOVED)) + { + continue; + } + } + // Limit to XARCH, ARM is already doing a great job with such comparisons using // a series of ccmp instruction (see ifConvert phase). #ifdef TARGET_XARCH