Skip to content

JIT: Simplify if-conversion#125347

Merged
jakobbotsch merged 9 commits intodotnet:mainfrom
BoyBaykiller:simplify-if-conv
Apr 15, 2026
Merged

JIT: Simplify if-conversion#125347
jakobbotsch merged 9 commits intodotnet:mainfrom
BoyBaykiller:simplify-if-conv

Conversation

@BoyBaykiller
Copy link
Copy Markdown
Contributor

@BoyBaykiller BoyBaykiller commented Mar 9, 2026

Zero-diff change that simplifies if-conversion based on the assumption that there are no empty blocks inside the Then and Else case. See: #125072 (comment)

@BoyBaykiller BoyBaykiller changed the title JIT: Simplify if conv JIT: Simplify if-conversion Mar 9, 2026
@github-actions github-actions bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 9, 2026
@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Mar 9, 2026
@dotnet-policy-service
Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR simplifies the CoreCLR JIT if-conversion implementation by collapsing the prior multi-block flow search into a single, direct-flow check, under the assumption that Then/Else paths do not contain empty/chained blocks.

Changes:

  • Replace the prior bounded “walk” of Then/Else chains with a single IfConvertCheckFlow() check.
  • Simplify statement validation to operate on a single block (ignoring NOPs) rather than scanning a block chain to m_finalBlock.
  • Simplify debug dumping and block removal to target only the identified Then/Else blocks.

Comment thread src/coreclr/jit/ifconversion.cpp
@BoyBaykiller
Copy link
Copy Markdown
Contributor Author

BoyBaykiller commented Mar 12, 2026

@a74nh @jakobbotsch What do you think? I guess the main question is whether this is a reasonable assumption to make in the first place:

assert(m_startBlock->GetFalseTarget()->GetUniqueSucc() == m_finalBlock);
if (m_doElseConversion)
{
    assert(m_startBlock->GetTrueTarget()->GetUniqueSucc() == m_finalBlock);
}

Meaning no flow through empty blocks inside Then/Else cases.
So CheckFlow becomes just https://github.com/BoyBaykiller/runtime/blob/5c1616c5d263ec7ef07a1da4b8bc8224cdf3b97c/src/coreclr/jit/ifconversion.cpp#L73-L101. No diffs. I think cases where previous phases produce empty blocks aren't amendable to if-conversion anyway.

I simplified:

  • CheckFlow
  • CheckStmts
  • Dump
  • removeBlocks

@a74nh
Copy link
Copy Markdown
Contributor

a74nh commented Mar 13, 2026

@a74nh @jakobbotsch What do you think? I guess the main question is whether this is a reasonable assumption to make in the first place:

assert(m_startBlock->GetFalseTarget()->GetUniqueSucc() == m_finalBlock);
if (m_doElseConversion)
{
    assert(m_startBlock->GetTrueTarget()->GetUniqueSucc() == m_finalBlock);
}

The original assumption was that the graph potentially could contain multiple blocks with a straight line flow between them. What could give that scenario?

  • reaching a max number of statements in a block? I'm not sure if there even is a limit
  • if a previous optimisation left the graph that way (for example, if conversion prior to your fix). But that's for the previous optimisation to be fixed up.
  • Nested if then, eg if (x) { if(y) {...} else {...} } else { ... }. But if conversion can't optimise that scenario anyway.
  • if (x && y && z) isn't quite the same scenario, but that will already be optimised by optimise bools into CCMPs that can then be if converted.

No diffs

Even if it's not a 100% correct assumption, sounds like we're still catching everything of relevance with your change.

@BoyBaykiller
Copy link
Copy Markdown
Contributor Author

Nested if then, eg if (x) { if(y) {...} else {...} } else { ... }. But if conversion can't optimise that scenario anyway.

Do you mean something like this. Because it does get recognized. We just bail on profitability for the outer one:
Skipping if-conversion that will evaluate RHS unconditionally at costs 9,1 .

int a74nh(bool x, bool y)
{
    if (x)
    {
        if (y)
        {
            return 1;
        }
        else
        {
            return 2;
        }
    }
    else
    {
        return 3;
    }
}
       mov      eax, 3
       mov      ecx, 2
       mov      r10d, 1
       test     r8b, r8b
       cmovne   ecx, r10d
       test     dl, dl
       cmovne   eax, ecx
						;; size=28 bbWeight=1 PerfScore 1.75
G_M25408_IG03:  ;; offset=0x001C
       ret      

Anyway so yeah, while there will still be Then/Else cases with multiple blocks that have linear flow this PR says: "Such cases won't be amendable to if-conversion anyway so let's bail in CheckFlow()".
Previously such cases would have been considered valid flow only to bail out in CheckStmts immediately after (with #125072).

Comment thread src/coreclr/jit/ifconversion.cpp Outdated
Comment thread src/coreclr/jit/ifconversion.cpp
Comment thread src/coreclr/jit/ifconversion.cpp Outdated
* add 'assert(m_cond->OperIsCompare())'
* combine IfConvertCheckFlow + IfConvertCheckStmts into new IfConvertCheck
* get m_mainOper from m_thenOperation instead of flow check
@BoyBaykiller
Copy link
Copy Markdown
Contributor Author

@a74nh does everything look ok now or are there other changes you would like me to do?

Copy link
Copy Markdown
Contributor

@a74nh a74nh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy with this now.
Although, looks like formatting needs fixing.

@jakobbotsch jakobbotsch self-requested a review March 24, 2026 10:01
@jakobbotsch
Copy link
Copy Markdown
Member

@BoyBaykiller Can you address the formatting issue?

@BoyBaykiller BoyBaykiller reopened this Apr 9, 2026
@jakobbotsch
Copy link
Copy Markdown
Member

jakobbotsch commented Apr 9, 2026

@BoyBaykiller The jit-format job uploads a patch file when the formatting fails that you can apply locally to fix it. You can also run jit-format locally before you even commit: https://github.com/dotnet/jitutils/blob/main/doc/formatting.md

@BoyBaykiller
Copy link
Copy Markdown
Contributor Author

Thanks. I'll know that for the future. In this case vscode formatting did the job

Copy link
Copy Markdown
Member

@jakobbotsch jakobbotsch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@jakobbotsch jakobbotsch merged commit dea4756 into dotnet:main Apr 15, 2026
144 of 148 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants