Repository: dotnet/runtime
File: src/coreclr/jit/fgopt.cpp (C++)

Code before:
        switchTree->AsOp()->gtOp1 = condNode;
        switchTree->AsOp()->gtOp1->gtFlags |= (GTF_RELOP_JMP_USED | GTF_DONT_CSE);

        if (block->IsLIR())
        {
            blockRange->InsertAfter(switchVal, zeroConstNode, condNode);
            LIR::ReadOnlyRange range(zeroConstNode, switchTree);
            m_pLowering->LowerRange(block, range);
        }
        else if (fgNodeThreading != NodeThreading::None)
        {
            gtSetStmtInfo(switchStmt);
            fgSetStmtSeq(switchStmt);
        }

        FlowEdge* const trueEdge  = block->GetSwitchTargets()->GetCase(0);
        FlowEdge* const falseEdge = block->GetSwitchTargets()->GetCase(1);
        block->SetCond(trueEdge, falseEdge);

        JITDUMP("After:\n");
        DISPNODE(switchTree);

        return true;
    }
    else if (block->GetSwitchTargets()->GetSuccCount() == 2 && block->GetSwitchTargets()->HasDefaultCase() &&
        (block->IsLIR() || fgNodeThreading == NodeThreading::AllTrees))
    {
        // If all non-default cases jump to one target and the default jumps to a different target,
        // replace the switch with an unsigned comparison against the max case index:
        //   GT_SWITCH(switchVal) -> GT_JTRUE(GT_LE/GT_GT(switchVal, caseCount - 2))
        // The comparison direction is chosen to favor fall-through to the next block.
        // When both targets are simple return blocks, fgFoldCondToReturnBlock can further
        // convert this into branchless codegen like "cmp; setbe" instead of a jump table.

        BBswtDesc*  switchDesc  = block->GetSwitchTargets();
        unsigned    caseCount   = switchDesc->GetCaseCount();

        // For small switches with 2 or fewer non-default cases (caseCount <= 3 including the default),
        // the backend's switch lowering already generates efficient comparison chains. Converting
        // early can enable if-conversion (cmov) that produces worse code for these cases.
        if (caseCount <= 3)
        {
            return modified;
        }

        FlowEdge*   defaultEdge = switchDesc->GetDefaultCase();
        BasicBlock* defaultDest = defaultEdge->getDestinationBlock();

        // Check that all non-default cases share the same target, distinct from the default target.
        FlowEdge*   firstCaseEdge = switchDesc->GetCase(0);
        BasicBlock* caseDest      = firstCaseEdge->getDestinationBlock();

Review comment (refactor):
Can we only do this for `!block->IsLIR()` I don't think it's beneficial to support LIR (Lower will handle such switches anyway). So we can simplify code by removing special cases for IsLIR()

Code after:
        switchTree->AsOp()->gtOp1 = condNode;
        switchTree->AsOp()->gtOp1->gtFlags |= (GTF_RELOP_JMP_USED | GTF_DONT_CSE);

        if (block->IsLIR())
        {
            blockRange->InsertAfter(switchVal, zeroConstNode, condNode);
            LIR::ReadOnlyRange range(zeroConstNode, switchTree);
            m_pLowering->LowerRange(block, range);
        }
        else if (fgNodeThreading != NodeThreading::None)
        {
            gtSetStmtInfo(switchStmt);
            fgSetStmtSeq(switchStmt);
        }

        FlowEdge* const trueEdge  = block->GetSwitchTargets()->GetCase(0);
        FlowEdge* const falseEdge = block->GetSwitchTargets()->GetCase(1);
        block->SetCond(trueEdge, falseEdge);

        JITDUMP("After:\n");
        DISPNODE(switchTree);

        return true;
    }
    else if (block->GetSwitchTargets()->GetSuccCount() == 2 && block->GetSwitchTargets()->HasDefaultCase() &&
             !block->IsLIR() && fgNodeThreading == NodeThreading::AllTrees)
    {
        // If all non-default cases jump to the same target and the default jumps to a different target,
        // replace the switch with an unsigned comparison against the max case index:
        //   GT_SWITCH(switchVal) -> GT_JTRUE(GT_LT(switchVal, caseCount))

        BBswtDesc* switchDesc = block->GetSwitchTargets();

        FlowEdge*   defaultEdge   = switchDesc->GetDefaultCase();
        BasicBlock* defaultDest   = defaultEdge->getDestinationBlock();
        FlowEdge*   firstCaseEdge = switchDesc->GetCase(0);
        BasicBlock* caseDest      = firstCaseEdge->getDestinationBlock();

        // Optimize only when all non-default cases share the same target, distinct from the default target.
        // Only the default case targets defaultDest.
        if (defaultEdge->getDupCount() != 1)
        {
            return modified;
        }

        JITDUMP("\nConverting a switch (" FMT_BB ") where all non-default cases target the same block to a "
                "conditional branch. Before:\n",
                block->bbNum);
        DISPNODE(switchTree);

        // Use GT_LT (e.g., switchVal < caseCount), so true (in range) goes to the shared case target and false (out of