Ignore PhiArgs without matching actual preds - #125093

Merged
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions
Mar 4, 2026
Merged

Ignore PhiArgs without matching actual preds#125093
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions

Conversation

@EgorBo

@EgorBoEgorBo commented Mar 3, 2026

Copy link
Copy Markdown
Member

Fixes#124507

A couple of diffs

CopilotAI review requested due to automatic review settings March 3, 2026 01:41
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 3, 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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates CoreCLR JIT’s assertion propagation through SSA PHI nodes to be more conservative when PHI arguments don’t correspond to actual CFG predecessors, and adds a regression test for #124507.

Changes:

  • Add a guard in optVisitReachingAssertions to abort PHI-based assertion inference when a PhiArg references a non-predecessor block.
  • Add a new JIT regression test Runtime_124507.
  • Wire the new test into Regression_ro_2.csproj.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

FileDescription
src/coreclr/jit/compiler.hppAbort PHI reaching-assertions walk when a PHI arg pred block is not an actual predecessor.
src/tests/JIT/Regression/Regression_ro_2.csprojIncludes the new Runtime_124507 regression test source file.
src/tests/JIT/Regression/JitBlue/Runtime_124507/Runtime_124507.csAdds a reduced repro as an xUnit test entry point for #124507.

CopilotAI review requested due to automatic review settings March 3, 2026 12:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment threadsrc/coreclr/jit/compiler.hpp
Comment threadsrc/coreclr/jit/compiler.hpp Outdated
CopilotAI review requested due to automatic review settings March 3, 2026 13:08

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@EgorBo
EgorBo marked this pull request as ready for review March 3, 2026 15:04
@EgorBo
EgorBo requested a review from AndyAyersMSMarch 3, 2026 16:08
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

PTAL @AndyAyersMS @dotnet/jit-contrib
I tried your suggestion with just checking two bitvectors in the end instead of the second pred walk, but Copilot suggested that it might be more expensive as we PHI don't have too many preds usually, but bitvectors might be long (fgMaxBlocks).

Also, I was not brave enough to just ignore PhiArgs without matching pred blocks (but if I do it, I get -200kb diff improvement).

@AndyAyersMS

Copy link
Copy Markdown
Member

Can you describe what goes wrong without this fix?

Naively I'd expect that if we considered assertions from preds that no longer reached we would only be more conservative.

CopilotAI review requested due to automatic review settings March 3, 2026 19:02
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS it turned out the actual bug was in optGetEdgeAssertions that returned incorrect assertions for an edge that doesn't exist (because of RBO) for that Phi.

I propose we still keep the optVisitReachingAssertions change (it's no longer necessary to fix the bug) since the regression is pretty small just in case. We can alter the PhiVN if we want and remove dead preds somewhere (e.g. in GlobalAP)

Comment threadsrc/coreclr/jit/assertionprop.cpp Outdated
CopilotAI reviewed Mar 3, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

CopilotAI review requested due to automatic review settings March 3, 2026 20:50

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@EgorBo

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS anything else? Diffs are relatively small (mostly from test collections)

Comment threadsrc/coreclr/jit/assertionprop.cpp

@AndyAyersMSAndyAyersMS left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@EgorBo

EgorBo commented Mar 4, 2026

Copy link
Copy Markdown
MemberAuthor

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@AndyAyersMS That is a very valid point. In GlobalAP when we use facts and fold comparisons into true/false, we call Morph for them that can convert BBJ_COND into BBJ_ALWAYS (e.g. via fgFoldConditional) and it currently doesn't do anything with what assertion vectors are valid. I can also take a look

@EgorBo

Copy link
Copy Markdown
MemberAuthor

/ba-g deadletter

@EgorBo
EgorBo enabled auto-merge (squash) March 4, 2026 19:18
@EgorBo
EgorBo merged commit 14c4360 into dotnet:mainMar 4, 2026
133 of 138 checks passed
@EgorBo
EgorBo deleted the fix-optVisitReachingAssertions branch March 4, 2026 19:19
EgorBo added a commit that referenced this pull request Mar 6, 2026
Address @AndyAyersMS concerns regarding assertion sets
(#125093 (review))
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 4, 2026
@dhartglassMSFT

Copy link
Copy Markdown
Contributor

/backport to release/10.0

@github-actionsgithub-actionsBot unlocked this conversation Jul 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

@dhartglassMSFT backporting to release/10.0 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patchApplying: ignore PhiArgs without real predsUsing index info to reconstruct a base tree...M	src/coreclr/jit/compiler.hppA	src/tests/JIT/Regression/Regression_ro_2.csprojFalling back to patching base and 3-way merge...Auto-merging src/coreclr/jit/compiler.hppCONFLICT (content): Merge conflict in src/coreclr/jit/compiler.hppCONFLICT (modify/delete): src/tests/JIT/Regression/Regression_ro_2.csproj deleted in HEAD and modified in ignore PhiArgs without real preds. Version ignore PhiArgs without real preds of src/tests/JIT/Regression/Regression_ro_2.csproj left in tree.error: Failed to merge in the changes.hint: Use 'git am --show-current-patch=diff' to see the failed patchhint: When you have resolved this problem, run "git am --continue".hint: If you prefer to skip this patch, run "git am --skip" instead.hint: To restore the original branch and stop patching, run "git am --abort".hint: Disable this message with "git config set advice.mergeConflict false"Patch failed at 0001 ignore PhiArgs without real predsError: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

@github-actionsgithub-actionsBot locked as resolved and limited conversation to collaborators Jul 14, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JIT: True branch not executed

4 participants

@EgorBo@AndyAyersMS@dhartglassMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Ignore PhiArgs without matching actual preds - #125093

Merged
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions
Mar 4, 2026
Merged

Ignore PhiArgs without matching actual preds#125093
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions

Conversation

@EgorBo

@EgorBoEgorBo commented Mar 3, 2026

Copy link
Copy Markdown
Member

Fixes#124507

A couple of diffs

CopilotAI review requested due to automatic review settings March 3, 2026 01:41
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 3, 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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates CoreCLR JIT’s assertion propagation through SSA PHI nodes to be more conservative when PHI arguments don’t correspond to actual CFG predecessors, and adds a regression test for #124507.

Changes:

  • Add a guard in optVisitReachingAssertions to abort PHI-based assertion inference when a PhiArg references a non-predecessor block.
  • Add a new JIT regression test Runtime_124507.
  • Wire the new test into Regression_ro_2.csproj.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

FileDescription
src/coreclr/jit/compiler.hppAbort PHI reaching-assertions walk when a PHI arg pred block is not an actual predecessor.
src/tests/JIT/Regression/Regression_ro_2.csprojIncludes the new Runtime_124507 regression test source file.
src/tests/JIT/Regression/JitBlue/Runtime_124507/Runtime_124507.csAdds a reduced repro as an xUnit test entry point for #124507.

CopilotAI review requested due to automatic review settings March 3, 2026 12:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment threadsrc/coreclr/jit/compiler.hpp
Comment threadsrc/coreclr/jit/compiler.hpp Outdated
CopilotAI review requested due to automatic review settings March 3, 2026 13:08

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@EgorBo
EgorBo marked this pull request as ready for review March 3, 2026 15:04
@EgorBo
EgorBo requested a review from AndyAyersMSMarch 3, 2026 16:08
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

PTAL @AndyAyersMS @dotnet/jit-contrib
I tried your suggestion with just checking two bitvectors in the end instead of the second pred walk, but Copilot suggested that it might be more expensive as we PHI don't have too many preds usually, but bitvectors might be long (fgMaxBlocks).

Also, I was not brave enough to just ignore PhiArgs without matching pred blocks (but if I do it, I get -200kb diff improvement).

@AndyAyersMS

Copy link
Copy Markdown
Member

Can you describe what goes wrong without this fix?

Naively I'd expect that if we considered assertions from preds that no longer reached we would only be more conservative.

CopilotAI review requested due to automatic review settings March 3, 2026 19:02
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS it turned out the actual bug was in optGetEdgeAssertions that returned incorrect assertions for an edge that doesn't exist (because of RBO) for that Phi.

I propose we still keep the optVisitReachingAssertions change (it's no longer necessary to fix the bug) since the regression is pretty small just in case. We can alter the PhiVN if we want and remove dead preds somewhere (e.g. in GlobalAP)

Comment threadsrc/coreclr/jit/assertionprop.cpp Outdated
CopilotAI reviewed Mar 3, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

CopilotAI review requested due to automatic review settings March 3, 2026 20:50

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@EgorBo

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS anything else? Diffs are relatively small (mostly from test collections)

Comment threadsrc/coreclr/jit/assertionprop.cpp

@AndyAyersMSAndyAyersMS left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@EgorBo

EgorBo commented Mar 4, 2026

Copy link
Copy Markdown
MemberAuthor

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@AndyAyersMS That is a very valid point. In GlobalAP when we use facts and fold comparisons into true/false, we call Morph for them that can convert BBJ_COND into BBJ_ALWAYS (e.g. via fgFoldConditional) and it currently doesn't do anything with what assertion vectors are valid. I can also take a look

@EgorBo

Copy link
Copy Markdown
MemberAuthor

/ba-g deadletter

@EgorBo
EgorBo enabled auto-merge (squash) March 4, 2026 19:18
@EgorBo
EgorBo merged commit 14c4360 into dotnet:mainMar 4, 2026
133 of 138 checks passed
@EgorBo
EgorBo deleted the fix-optVisitReachingAssertions branch March 4, 2026 19:19
EgorBo added a commit that referenced this pull request Mar 6, 2026
Address @AndyAyersMS concerns regarding assertion sets
(#125093 (review))
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 4, 2026
@dhartglassMSFT

Copy link
Copy Markdown
Contributor

/backport to release/10.0

@github-actionsgithub-actionsBot unlocked this conversation Jul 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

@dhartglassMSFT backporting to release/10.0 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patchApplying: ignore PhiArgs without real predsUsing index info to reconstruct a base tree...M	src/coreclr/jit/compiler.hppA	src/tests/JIT/Regression/Regression_ro_2.csprojFalling back to patching base and 3-way merge...Auto-merging src/coreclr/jit/compiler.hppCONFLICT (content): Merge conflict in src/coreclr/jit/compiler.hppCONFLICT (modify/delete): src/tests/JIT/Regression/Regression_ro_2.csproj deleted in HEAD and modified in ignore PhiArgs without real preds. Version ignore PhiArgs without real preds of src/tests/JIT/Regression/Regression_ro_2.csproj left in tree.error: Failed to merge in the changes.hint: Use 'git am --show-current-patch=diff' to see the failed patchhint: When you have resolved this problem, run "git am --continue".hint: If you prefer to skip this patch, run "git am --skip" instead.hint: To restore the original branch and stop patching, run "git am --abort".hint: Disable this message with "git config set advice.mergeConflict false"Patch failed at 0001 ignore PhiArgs without real predsError: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

@github-actionsgithub-actionsBot locked as resolved and limited conversation to collaborators Jul 14, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JIT: True branch not executed

4 participants

@EgorBo@AndyAyersMS@dhartglassMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Ignore PhiArgs without matching actual preds - #125093

Merged
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions
Mar 4, 2026
Merged

Ignore PhiArgs without matching actual preds#125093
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions

Conversation

@EgorBo

@EgorBoEgorBo commented Mar 3, 2026

Copy link
Copy Markdown
Member

Fixes#124507

A couple of diffs

CopilotAI review requested due to automatic review settings March 3, 2026 01:41
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 3, 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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates CoreCLR JIT’s assertion propagation through SSA PHI nodes to be more conservative when PHI arguments don’t correspond to actual CFG predecessors, and adds a regression test for #124507.

Changes:

  • Add a guard in optVisitReachingAssertions to abort PHI-based assertion inference when a PhiArg references a non-predecessor block.
  • Add a new JIT regression test Runtime_124507.
  • Wire the new test into Regression_ro_2.csproj.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

FileDescription
src/coreclr/jit/compiler.hppAbort PHI reaching-assertions walk when a PHI arg pred block is not an actual predecessor.
src/tests/JIT/Regression/Regression_ro_2.csprojIncludes the new Runtime_124507 regression test source file.
src/tests/JIT/Regression/JitBlue/Runtime_124507/Runtime_124507.csAdds a reduced repro as an xUnit test entry point for #124507.

CopilotAI review requested due to automatic review settings March 3, 2026 12:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment threadsrc/coreclr/jit/compiler.hpp
Comment threadsrc/coreclr/jit/compiler.hpp Outdated
CopilotAI review requested due to automatic review settings March 3, 2026 13:08

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@EgorBo
EgorBo marked this pull request as ready for review March 3, 2026 15:04
@EgorBo
EgorBo requested a review from AndyAyersMSMarch 3, 2026 16:08
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

PTAL @AndyAyersMS @dotnet/jit-contrib
I tried your suggestion with just checking two bitvectors in the end instead of the second pred walk, but Copilot suggested that it might be more expensive as we PHI don't have too many preds usually, but bitvectors might be long (fgMaxBlocks).

Also, I was not brave enough to just ignore PhiArgs without matching pred blocks (but if I do it, I get -200kb diff improvement).

@AndyAyersMS

Copy link
Copy Markdown
Member

Can you describe what goes wrong without this fix?

Naively I'd expect that if we considered assertions from preds that no longer reached we would only be more conservative.

CopilotAI review requested due to automatic review settings March 3, 2026 19:02
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS it turned out the actual bug was in optGetEdgeAssertions that returned incorrect assertions for an edge that doesn't exist (because of RBO) for that Phi.

I propose we still keep the optVisitReachingAssertions change (it's no longer necessary to fix the bug) since the regression is pretty small just in case. We can alter the PhiVN if we want and remove dead preds somewhere (e.g. in GlobalAP)

Comment threadsrc/coreclr/jit/assertionprop.cpp Outdated
CopilotAI reviewed Mar 3, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

CopilotAI review requested due to automatic review settings March 3, 2026 20:50

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@EgorBo

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS anything else? Diffs are relatively small (mostly from test collections)

Comment threadsrc/coreclr/jit/assertionprop.cpp

@AndyAyersMSAndyAyersMS left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@EgorBo

EgorBo commented Mar 4, 2026

Copy link
Copy Markdown
MemberAuthor

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@AndyAyersMS That is a very valid point. In GlobalAP when we use facts and fold comparisons into true/false, we call Morph for them that can convert BBJ_COND into BBJ_ALWAYS (e.g. via fgFoldConditional) and it currently doesn't do anything with what assertion vectors are valid. I can also take a look

@EgorBo

Copy link
Copy Markdown
MemberAuthor

/ba-g deadletter

@EgorBo
EgorBo enabled auto-merge (squash) March 4, 2026 19:18
@EgorBo
EgorBo merged commit 14c4360 into dotnet:mainMar 4, 2026
133 of 138 checks passed
@EgorBo
EgorBo deleted the fix-optVisitReachingAssertions branch March 4, 2026 19:19
EgorBo added a commit that referenced this pull request Mar 6, 2026
Address @AndyAyersMS concerns regarding assertion sets
(#125093 (review))
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 4, 2026
@dhartglassMSFT

Copy link
Copy Markdown
Contributor

/backport to release/10.0

@github-actionsgithub-actionsBot unlocked this conversation Jul 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

@dhartglassMSFT backporting to release/10.0 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patchApplying: ignore PhiArgs without real predsUsing index info to reconstruct a base tree...M	src/coreclr/jit/compiler.hppA	src/tests/JIT/Regression/Regression_ro_2.csprojFalling back to patching base and 3-way merge...Auto-merging src/coreclr/jit/compiler.hppCONFLICT (content): Merge conflict in src/coreclr/jit/compiler.hppCONFLICT (modify/delete): src/tests/JIT/Regression/Regression_ro_2.csproj deleted in HEAD and modified in ignore PhiArgs without real preds. Version ignore PhiArgs without real preds of src/tests/JIT/Regression/Regression_ro_2.csproj left in tree.error: Failed to merge in the changes.hint: Use 'git am --show-current-patch=diff' to see the failed patchhint: When you have resolved this problem, run "git am --continue".hint: If you prefer to skip this patch, run "git am --skip" instead.hint: To restore the original branch and stop patching, run "git am --abort".hint: Disable this message with "git config set advice.mergeConflict false"Patch failed at 0001 ignore PhiArgs without real predsError: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

@github-actionsgithub-actionsBot locked as resolved and limited conversation to collaborators Jul 14, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JIT: True branch not executed

4 participants

@EgorBo@AndyAyersMS@dhartglassMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Ignore PhiArgs without matching actual preds - #125093

Merged
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions
Mar 4, 2026
Merged

Ignore PhiArgs without matching actual preds#125093
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions

Conversation

@EgorBo

@EgorBoEgorBo commented Mar 3, 2026

Copy link
Copy Markdown
Member

Fixes#124507

A couple of diffs

CopilotAI review requested due to automatic review settings March 3, 2026 01:41
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 3, 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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates CoreCLR JIT’s assertion propagation through SSA PHI nodes to be more conservative when PHI arguments don’t correspond to actual CFG predecessors, and adds a regression test for #124507.

Changes:

  • Add a guard in optVisitReachingAssertions to abort PHI-based assertion inference when a PhiArg references a non-predecessor block.
  • Add a new JIT regression test Runtime_124507.
  • Wire the new test into Regression_ro_2.csproj.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

FileDescription
src/coreclr/jit/compiler.hppAbort PHI reaching-assertions walk when a PHI arg pred block is not an actual predecessor.
src/tests/JIT/Regression/Regression_ro_2.csprojIncludes the new Runtime_124507 regression test source file.
src/tests/JIT/Regression/JitBlue/Runtime_124507/Runtime_124507.csAdds a reduced repro as an xUnit test entry point for #124507.

CopilotAI review requested due to automatic review settings March 3, 2026 12:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment threadsrc/coreclr/jit/compiler.hpp
Comment threadsrc/coreclr/jit/compiler.hpp Outdated
CopilotAI review requested due to automatic review settings March 3, 2026 13:08

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@EgorBo
EgorBo marked this pull request as ready for review March 3, 2026 15:04
@EgorBo
EgorBo requested a review from AndyAyersMSMarch 3, 2026 16:08
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

PTAL @AndyAyersMS @dotnet/jit-contrib
I tried your suggestion with just checking two bitvectors in the end instead of the second pred walk, but Copilot suggested that it might be more expensive as we PHI don't have too many preds usually, but bitvectors might be long (fgMaxBlocks).

Also, I was not brave enough to just ignore PhiArgs without matching pred blocks (but if I do it, I get -200kb diff improvement).

@AndyAyersMS

Copy link
Copy Markdown
Member

Can you describe what goes wrong without this fix?

Naively I'd expect that if we considered assertions from preds that no longer reached we would only be more conservative.

CopilotAI review requested due to automatic review settings March 3, 2026 19:02
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS it turned out the actual bug was in optGetEdgeAssertions that returned incorrect assertions for an edge that doesn't exist (because of RBO) for that Phi.

I propose we still keep the optVisitReachingAssertions change (it's no longer necessary to fix the bug) since the regression is pretty small just in case. We can alter the PhiVN if we want and remove dead preds somewhere (e.g. in GlobalAP)

Comment threadsrc/coreclr/jit/assertionprop.cpp Outdated
CopilotAI reviewed Mar 3, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

CopilotAI review requested due to automatic review settings March 3, 2026 20:50

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@EgorBo

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS anything else? Diffs are relatively small (mostly from test collections)

Comment threadsrc/coreclr/jit/assertionprop.cpp

@AndyAyersMSAndyAyersMS left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@EgorBo

EgorBo commented Mar 4, 2026

Copy link
Copy Markdown
MemberAuthor

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@AndyAyersMS That is a very valid point. In GlobalAP when we use facts and fold comparisons into true/false, we call Morph for them that can convert BBJ_COND into BBJ_ALWAYS (e.g. via fgFoldConditional) and it currently doesn't do anything with what assertion vectors are valid. I can also take a look

@EgorBo

Copy link
Copy Markdown
MemberAuthor

/ba-g deadletter

@EgorBo
EgorBo enabled auto-merge (squash) March 4, 2026 19:18
@EgorBo
EgorBo merged commit 14c4360 into dotnet:mainMar 4, 2026
133 of 138 checks passed
@EgorBo
EgorBo deleted the fix-optVisitReachingAssertions branch March 4, 2026 19:19
EgorBo added a commit that referenced this pull request Mar 6, 2026
Address @AndyAyersMS concerns regarding assertion sets
(#125093 (review))
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 4, 2026
@dhartglassMSFT

Copy link
Copy Markdown
Contributor

/backport to release/10.0

@github-actionsgithub-actionsBot unlocked this conversation Jul 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

@dhartglassMSFT backporting to release/10.0 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patchApplying: ignore PhiArgs without real predsUsing index info to reconstruct a base tree...M	src/coreclr/jit/compiler.hppA	src/tests/JIT/Regression/Regression_ro_2.csprojFalling back to patching base and 3-way merge...Auto-merging src/coreclr/jit/compiler.hppCONFLICT (content): Merge conflict in src/coreclr/jit/compiler.hppCONFLICT (modify/delete): src/tests/JIT/Regression/Regression_ro_2.csproj deleted in HEAD and modified in ignore PhiArgs without real preds. Version ignore PhiArgs without real preds of src/tests/JIT/Regression/Regression_ro_2.csproj left in tree.error: Failed to merge in the changes.hint: Use 'git am --show-current-patch=diff' to see the failed patchhint: When you have resolved this problem, run "git am --continue".hint: If you prefer to skip this patch, run "git am --skip" instead.hint: To restore the original branch and stop patching, run "git am --abort".hint: Disable this message with "git config set advice.mergeConflict false"Patch failed at 0001 ignore PhiArgs without real predsError: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

@github-actionsgithub-actionsBot locked as resolved and limited conversation to collaborators Jul 14, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JIT: True branch not executed

4 participants

@EgorBo@AndyAyersMS@dhartglassMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Ignore PhiArgs without matching actual preds - #125093

Merged
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions
Mar 4, 2026
Merged

Ignore PhiArgs without matching actual preds#125093
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions

Conversation

@EgorBo

@EgorBoEgorBo commented Mar 3, 2026

Copy link
Copy Markdown
Member

Fixes#124507

A couple of diffs

CopilotAI review requested due to automatic review settings March 3, 2026 01:41
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 3, 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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates CoreCLR JIT’s assertion propagation through SSA PHI nodes to be more conservative when PHI arguments don’t correspond to actual CFG predecessors, and adds a regression test for #124507.

Changes:

  • Add a guard in optVisitReachingAssertions to abort PHI-based assertion inference when a PhiArg references a non-predecessor block.
  • Add a new JIT regression test Runtime_124507.
  • Wire the new test into Regression_ro_2.csproj.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

FileDescription
src/coreclr/jit/compiler.hppAbort PHI reaching-assertions walk when a PHI arg pred block is not an actual predecessor.
src/tests/JIT/Regression/Regression_ro_2.csprojIncludes the new Runtime_124507 regression test source file.
src/tests/JIT/Regression/JitBlue/Runtime_124507/Runtime_124507.csAdds a reduced repro as an xUnit test entry point for #124507.

CopilotAI review requested due to automatic review settings March 3, 2026 12:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment threadsrc/coreclr/jit/compiler.hpp
Comment threadsrc/coreclr/jit/compiler.hpp Outdated
CopilotAI review requested due to automatic review settings March 3, 2026 13:08

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@EgorBo
EgorBo marked this pull request as ready for review March 3, 2026 15:04
@EgorBo
EgorBo requested a review from AndyAyersMSMarch 3, 2026 16:08
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

PTAL @AndyAyersMS @dotnet/jit-contrib
I tried your suggestion with just checking two bitvectors in the end instead of the second pred walk, but Copilot suggested that it might be more expensive as we PHI don't have too many preds usually, but bitvectors might be long (fgMaxBlocks).

Also, I was not brave enough to just ignore PhiArgs without matching pred blocks (but if I do it, I get -200kb diff improvement).

@AndyAyersMS

Copy link
Copy Markdown
Member

Can you describe what goes wrong without this fix?

Naively I'd expect that if we considered assertions from preds that no longer reached we would only be more conservative.

CopilotAI review requested due to automatic review settings March 3, 2026 19:02
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS it turned out the actual bug was in optGetEdgeAssertions that returned incorrect assertions for an edge that doesn't exist (because of RBO) for that Phi.

I propose we still keep the optVisitReachingAssertions change (it's no longer necessary to fix the bug) since the regression is pretty small just in case. We can alter the PhiVN if we want and remove dead preds somewhere (e.g. in GlobalAP)

Comment threadsrc/coreclr/jit/assertionprop.cpp Outdated
CopilotAI reviewed Mar 3, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

CopilotAI review requested due to automatic review settings March 3, 2026 20:50

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@EgorBo

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS anything else? Diffs are relatively small (mostly from test collections)

Comment threadsrc/coreclr/jit/assertionprop.cpp

@AndyAyersMSAndyAyersMS left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@EgorBo

EgorBo commented Mar 4, 2026

Copy link
Copy Markdown
MemberAuthor

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@AndyAyersMS That is a very valid point. In GlobalAP when we use facts and fold comparisons into true/false, we call Morph for them that can convert BBJ_COND into BBJ_ALWAYS (e.g. via fgFoldConditional) and it currently doesn't do anything with what assertion vectors are valid. I can also take a look

@EgorBo

Copy link
Copy Markdown
MemberAuthor

/ba-g deadletter

@EgorBo
EgorBo enabled auto-merge (squash) March 4, 2026 19:18
@EgorBo
EgorBo merged commit 14c4360 into dotnet:mainMar 4, 2026
133 of 138 checks passed
@EgorBo
EgorBo deleted the fix-optVisitReachingAssertions branch March 4, 2026 19:19
EgorBo added a commit that referenced this pull request Mar 6, 2026
Address @AndyAyersMS concerns regarding assertion sets
(#125093 (review))
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 4, 2026
@dhartglassMSFT

Copy link
Copy Markdown
Contributor

/backport to release/10.0

@github-actionsgithub-actionsBot unlocked this conversation Jul 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

@dhartglassMSFT backporting to release/10.0 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patchApplying: ignore PhiArgs without real predsUsing index info to reconstruct a base tree...M	src/coreclr/jit/compiler.hppA	src/tests/JIT/Regression/Regression_ro_2.csprojFalling back to patching base and 3-way merge...Auto-merging src/coreclr/jit/compiler.hppCONFLICT (content): Merge conflict in src/coreclr/jit/compiler.hppCONFLICT (modify/delete): src/tests/JIT/Regression/Regression_ro_2.csproj deleted in HEAD and modified in ignore PhiArgs without real preds. Version ignore PhiArgs without real preds of src/tests/JIT/Regression/Regression_ro_2.csproj left in tree.error: Failed to merge in the changes.hint: Use 'git am --show-current-patch=diff' to see the failed patchhint: When you have resolved this problem, run "git am --continue".hint: If you prefer to skip this patch, run "git am --skip" instead.hint: To restore the original branch and stop patching, run "git am --abort".hint: Disable this message with "git config set advice.mergeConflict false"Patch failed at 0001 ignore PhiArgs without real predsError: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

@github-actionsgithub-actionsBot locked as resolved and limited conversation to collaborators Jul 14, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JIT: True branch not executed

4 participants

@EgorBo@AndyAyersMS@dhartglassMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Ignore PhiArgs without matching actual preds - #125093

Merged
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions
Mar 4, 2026
Merged

Ignore PhiArgs without matching actual preds#125093
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions

Conversation

@EgorBo

@EgorBoEgorBo commented Mar 3, 2026

Copy link
Copy Markdown
Member

Fixes#124507

A couple of diffs

CopilotAI review requested due to automatic review settings March 3, 2026 01:41
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 3, 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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates CoreCLR JIT’s assertion propagation through SSA PHI nodes to be more conservative when PHI arguments don’t correspond to actual CFG predecessors, and adds a regression test for #124507.

Changes:

  • Add a guard in optVisitReachingAssertions to abort PHI-based assertion inference when a PhiArg references a non-predecessor block.
  • Add a new JIT regression test Runtime_124507.
  • Wire the new test into Regression_ro_2.csproj.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

FileDescription
src/coreclr/jit/compiler.hppAbort PHI reaching-assertions walk when a PHI arg pred block is not an actual predecessor.
src/tests/JIT/Regression/Regression_ro_2.csprojIncludes the new Runtime_124507 regression test source file.
src/tests/JIT/Regression/JitBlue/Runtime_124507/Runtime_124507.csAdds a reduced repro as an xUnit test entry point for #124507.

CopilotAI review requested due to automatic review settings March 3, 2026 12:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment threadsrc/coreclr/jit/compiler.hpp
Comment threadsrc/coreclr/jit/compiler.hpp Outdated
CopilotAI review requested due to automatic review settings March 3, 2026 13:08

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@EgorBo
EgorBo marked this pull request as ready for review March 3, 2026 15:04
@EgorBo
EgorBo requested a review from AndyAyersMSMarch 3, 2026 16:08
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

PTAL @AndyAyersMS @dotnet/jit-contrib
I tried your suggestion with just checking two bitvectors in the end instead of the second pred walk, but Copilot suggested that it might be more expensive as we PHI don't have too many preds usually, but bitvectors might be long (fgMaxBlocks).

Also, I was not brave enough to just ignore PhiArgs without matching pred blocks (but if I do it, I get -200kb diff improvement).

@AndyAyersMS

Copy link
Copy Markdown
Member

Can you describe what goes wrong without this fix?

Naively I'd expect that if we considered assertions from preds that no longer reached we would only be more conservative.

CopilotAI review requested due to automatic review settings March 3, 2026 19:02
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS it turned out the actual bug was in optGetEdgeAssertions that returned incorrect assertions for an edge that doesn't exist (because of RBO) for that Phi.

I propose we still keep the optVisitReachingAssertions change (it's no longer necessary to fix the bug) since the regression is pretty small just in case. We can alter the PhiVN if we want and remove dead preds somewhere (e.g. in GlobalAP)

Comment threadsrc/coreclr/jit/assertionprop.cpp Outdated
CopilotAI reviewed Mar 3, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

CopilotAI review requested due to automatic review settings March 3, 2026 20:50

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@EgorBo

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS anything else? Diffs are relatively small (mostly from test collections)

Comment threadsrc/coreclr/jit/assertionprop.cpp

@AndyAyersMSAndyAyersMS left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@EgorBo

EgorBo commented Mar 4, 2026

Copy link
Copy Markdown
MemberAuthor

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@AndyAyersMS That is a very valid point. In GlobalAP when we use facts and fold comparisons into true/false, we call Morph for them that can convert BBJ_COND into BBJ_ALWAYS (e.g. via fgFoldConditional) and it currently doesn't do anything with what assertion vectors are valid. I can also take a look

@EgorBo

Copy link
Copy Markdown
MemberAuthor

/ba-g deadletter

@EgorBo
EgorBo enabled auto-merge (squash) March 4, 2026 19:18
@EgorBo
EgorBo merged commit 14c4360 into dotnet:mainMar 4, 2026
133 of 138 checks passed
@EgorBo
EgorBo deleted the fix-optVisitReachingAssertions branch March 4, 2026 19:19
EgorBo added a commit that referenced this pull request Mar 6, 2026
Address @AndyAyersMS concerns regarding assertion sets
(#125093 (review))
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 4, 2026
@dhartglassMSFT

Copy link
Copy Markdown
Contributor

/backport to release/10.0

@github-actionsgithub-actionsBot unlocked this conversation Jul 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

@dhartglassMSFT backporting to release/10.0 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patchApplying: ignore PhiArgs without real predsUsing index info to reconstruct a base tree...M	src/coreclr/jit/compiler.hppA	src/tests/JIT/Regression/Regression_ro_2.csprojFalling back to patching base and 3-way merge...Auto-merging src/coreclr/jit/compiler.hppCONFLICT (content): Merge conflict in src/coreclr/jit/compiler.hppCONFLICT (modify/delete): src/tests/JIT/Regression/Regression_ro_2.csproj deleted in HEAD and modified in ignore PhiArgs without real preds. Version ignore PhiArgs without real preds of src/tests/JIT/Regression/Regression_ro_2.csproj left in tree.error: Failed to merge in the changes.hint: Use 'git am --show-current-patch=diff' to see the failed patchhint: When you have resolved this problem, run "git am --continue".hint: If you prefer to skip this patch, run "git am --skip" instead.hint: To restore the original branch and stop patching, run "git am --abort".hint: Disable this message with "git config set advice.mergeConflict false"Patch failed at 0001 ignore PhiArgs without real predsError: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

@github-actionsgithub-actionsBot locked as resolved and limited conversation to collaborators Jul 14, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JIT: True branch not executed

4 participants

@EgorBo@AndyAyersMS@dhartglassMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Ignore PhiArgs without matching actual preds - #125093

Merged
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions
Mar 4, 2026
Merged

Ignore PhiArgs without matching actual preds#125093
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions

Conversation

@EgorBo

@EgorBoEgorBo commented Mar 3, 2026

Copy link
Copy Markdown
Member

Fixes#124507

A couple of diffs

CopilotAI review requested due to automatic review settings March 3, 2026 01:41
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 3, 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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates CoreCLR JIT’s assertion propagation through SSA PHI nodes to be more conservative when PHI arguments don’t correspond to actual CFG predecessors, and adds a regression test for #124507.

Changes:

  • Add a guard in optVisitReachingAssertions to abort PHI-based assertion inference when a PhiArg references a non-predecessor block.
  • Add a new JIT regression test Runtime_124507.
  • Wire the new test into Regression_ro_2.csproj.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

FileDescription
src/coreclr/jit/compiler.hppAbort PHI reaching-assertions walk when a PHI arg pred block is not an actual predecessor.
src/tests/JIT/Regression/Regression_ro_2.csprojIncludes the new Runtime_124507 regression test source file.
src/tests/JIT/Regression/JitBlue/Runtime_124507/Runtime_124507.csAdds a reduced repro as an xUnit test entry point for #124507.

CopilotAI review requested due to automatic review settings March 3, 2026 12:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment threadsrc/coreclr/jit/compiler.hpp
Comment threadsrc/coreclr/jit/compiler.hpp Outdated
CopilotAI review requested due to automatic review settings March 3, 2026 13:08

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@EgorBo
EgorBo marked this pull request as ready for review March 3, 2026 15:04
@EgorBo
EgorBo requested a review from AndyAyersMSMarch 3, 2026 16:08
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

PTAL @AndyAyersMS @dotnet/jit-contrib
I tried your suggestion with just checking two bitvectors in the end instead of the second pred walk, but Copilot suggested that it might be more expensive as we PHI don't have too many preds usually, but bitvectors might be long (fgMaxBlocks).

Also, I was not brave enough to just ignore PhiArgs without matching pred blocks (but if I do it, I get -200kb diff improvement).

@AndyAyersMS

Copy link
Copy Markdown
Member

Can you describe what goes wrong without this fix?

Naively I'd expect that if we considered assertions from preds that no longer reached we would only be more conservative.

CopilotAI review requested due to automatic review settings March 3, 2026 19:02
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS it turned out the actual bug was in optGetEdgeAssertions that returned incorrect assertions for an edge that doesn't exist (because of RBO) for that Phi.

I propose we still keep the optVisitReachingAssertions change (it's no longer necessary to fix the bug) since the regression is pretty small just in case. We can alter the PhiVN if we want and remove dead preds somewhere (e.g. in GlobalAP)

Comment threadsrc/coreclr/jit/assertionprop.cpp Outdated
CopilotAI reviewed Mar 3, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

CopilotAI review requested due to automatic review settings March 3, 2026 20:50

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@EgorBo

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS anything else? Diffs are relatively small (mostly from test collections)

Comment threadsrc/coreclr/jit/assertionprop.cpp

@AndyAyersMSAndyAyersMS left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@EgorBo

EgorBo commented Mar 4, 2026

Copy link
Copy Markdown
MemberAuthor

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@AndyAyersMS That is a very valid point. In GlobalAP when we use facts and fold comparisons into true/false, we call Morph for them that can convert BBJ_COND into BBJ_ALWAYS (e.g. via fgFoldConditional) and it currently doesn't do anything with what assertion vectors are valid. I can also take a look

@EgorBo

Copy link
Copy Markdown
MemberAuthor

/ba-g deadletter

@EgorBo
EgorBo enabled auto-merge (squash) March 4, 2026 19:18
@EgorBo
EgorBo merged commit 14c4360 into dotnet:mainMar 4, 2026
133 of 138 checks passed
@EgorBo
EgorBo deleted the fix-optVisitReachingAssertions branch March 4, 2026 19:19
EgorBo added a commit that referenced this pull request Mar 6, 2026
Address @AndyAyersMS concerns regarding assertion sets
(#125093 (review))
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 4, 2026
@dhartglassMSFT

Copy link
Copy Markdown
Contributor

/backport to release/10.0

@github-actionsgithub-actionsBot unlocked this conversation Jul 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

@dhartglassMSFT backporting to release/10.0 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patchApplying: ignore PhiArgs without real predsUsing index info to reconstruct a base tree...M	src/coreclr/jit/compiler.hppA	src/tests/JIT/Regression/Regression_ro_2.csprojFalling back to patching base and 3-way merge...Auto-merging src/coreclr/jit/compiler.hppCONFLICT (content): Merge conflict in src/coreclr/jit/compiler.hppCONFLICT (modify/delete): src/tests/JIT/Regression/Regression_ro_2.csproj deleted in HEAD and modified in ignore PhiArgs without real preds. Version ignore PhiArgs without real preds of src/tests/JIT/Regression/Regression_ro_2.csproj left in tree.error: Failed to merge in the changes.hint: Use 'git am --show-current-patch=diff' to see the failed patchhint: When you have resolved this problem, run "git am --continue".hint: If you prefer to skip this patch, run "git am --skip" instead.hint: To restore the original branch and stop patching, run "git am --abort".hint: Disable this message with "git config set advice.mergeConflict false"Patch failed at 0001 ignore PhiArgs without real predsError: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

@github-actionsgithub-actionsBot locked as resolved and limited conversation to collaborators Jul 14, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JIT: True branch not executed

4 participants

@EgorBo@AndyAyersMS@dhartglassMSFT
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Ignore PhiArgs without matching actual preds - #125093

Merged
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions
Mar 4, 2026
Merged

Ignore PhiArgs without matching actual preds#125093
EgorBo merged 13 commits into
dotnet:mainfrom
EgorBo:fix-optVisitReachingAssertions

Conversation

@EgorBo

@EgorBoEgorBo commented Mar 3, 2026

Copy link
Copy Markdown
Member

Fixes#124507

A couple of diffs

CopilotAI review requested due to automatic review settings March 3, 2026 01:41
@github-actionsgithub-actionsBot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 3, 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.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates CoreCLR JIT’s assertion propagation through SSA PHI nodes to be more conservative when PHI arguments don’t correspond to actual CFG predecessors, and adds a regression test for #124507.

Changes:

  • Add a guard in optVisitReachingAssertions to abort PHI-based assertion inference when a PhiArg references a non-predecessor block.
  • Add a new JIT regression test Runtime_124507.
  • Wire the new test into Regression_ro_2.csproj.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

FileDescription
src/coreclr/jit/compiler.hppAbort PHI reaching-assertions walk when a PHI arg pred block is not an actual predecessor.
src/tests/JIT/Regression/Regression_ro_2.csprojIncludes the new Runtime_124507 regression test source file.
src/tests/JIT/Regression/JitBlue/Runtime_124507/Runtime_124507.csAdds a reduced repro as an xUnit test entry point for #124507.

CopilotAI review requested due to automatic review settings March 3, 2026 12:48

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

Comment threadsrc/coreclr/jit/compiler.hpp
Comment threadsrc/coreclr/jit/compiler.hpp Outdated
CopilotAI review requested due to automatic review settings March 3, 2026 13:08

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@EgorBo
EgorBo marked this pull request as ready for review March 3, 2026 15:04
@EgorBo
EgorBo requested a review from AndyAyersMSMarch 3, 2026 16:08
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

PTAL @AndyAyersMS @dotnet/jit-contrib
I tried your suggestion with just checking two bitvectors in the end instead of the second pred walk, but Copilot suggested that it might be more expensive as we PHI don't have too many preds usually, but bitvectors might be long (fgMaxBlocks).

Also, I was not brave enough to just ignore PhiArgs without matching pred blocks (but if I do it, I get -200kb diff improvement).

@AndyAyersMS

Copy link
Copy Markdown
Member

Can you describe what goes wrong without this fix?

Naively I'd expect that if we considered assertions from preds that no longer reached we would only be more conservative.

CopilotAI review requested due to automatic review settings March 3, 2026 19:02
@EgorBo

EgorBo commented Mar 3, 2026

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS it turned out the actual bug was in optGetEdgeAssertions that returned incorrect assertions for an edge that doesn't exist (because of RBO) for that Phi.

I propose we still keep the optVisitReachingAssertions change (it's no longer necessary to fix the bug) since the regression is pretty small just in case. We can alter the PhiVN if we want and remove dead preds somewhere (e.g. in GlobalAP)

Comment threadsrc/coreclr/jit/assertionprop.cpp Outdated
CopilotAI reviewed Mar 3, 2026

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

CopilotAI review requested due to automatic review settings March 3, 2026 20:50

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

@EgorBo

Copy link
Copy Markdown
MemberAuthor

@AndyAyersMS anything else? Diffs are relatively small (mostly from test collections)

Comment threadsrc/coreclr/jit/assertionprop.cpp

@AndyAyersMSAndyAyersMS left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@EgorBo

EgorBo commented Mar 4, 2026

Copy link
Copy Markdown
MemberAuthor

I have one more concern but we can address it in a follow up.

For BBJ_COND we're producing two assertion sets, one for true and one for false. It looks like the false assertion set can take advantage of knowing the JTRUE predicate is false, at least in some cases.

Now suppose something in AP modifies flow so that the BBJ_COND becomes BBJ_ALWAYS (by say resolving the JTRUE to be true and removing the false successor edge).

Now we try backwards assertion refinement like we've been increasingly doing. Successors will now look at the "false" bb assertion set from this block, but that might be wrong since it was produced assuming the predicate was false.

Seems like if we change BBJ_COND into BBJ_ALWAYS based on a true predicate, we need overwrite the "if false" assertion set with the "if true" assertion set...?

An alternative is to have the false assertion set represent the set of assertions that are true independent of the JTRUE outcome.

(similar considerations would apply in Morph with local AP, but I don't think we do any backwards refinement there)

@AndyAyersMS That is a very valid point. In GlobalAP when we use facts and fold comparisons into true/false, we call Morph for them that can convert BBJ_COND into BBJ_ALWAYS (e.g. via fgFoldConditional) and it currently doesn't do anything with what assertion vectors are valid. I can also take a look

@EgorBo

Copy link
Copy Markdown
MemberAuthor

/ba-g deadletter

@EgorBo
EgorBo enabled auto-merge (squash) March 4, 2026 19:18
@EgorBo
EgorBo merged commit 14c4360 into dotnet:mainMar 4, 2026
133 of 138 checks passed
@EgorBo
EgorBo deleted the fix-optVisitReachingAssertions branch March 4, 2026 19:19
EgorBo added a commit that referenced this pull request Mar 6, 2026
Address @AndyAyersMS concerns regarding assertion sets
(#125093 (review))
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Apr 4, 2026
@dhartglassMSFT

Copy link
Copy Markdown
Contributor

/backport to release/10.0

@github-actionsgithub-actionsBot unlocked this conversation Jul 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/10.0 (link to workflow run)

@github-actions

Copy link
Copy Markdown
Contributor

@dhartglassMSFT backporting to release/10.0 failed, the patch most likely resulted in conflicts. Please backport manually!

git am output
$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patchApplying: ignore PhiArgs without real predsUsing index info to reconstruct a base tree...M	src/coreclr/jit/compiler.hppA	src/tests/JIT/Regression/Regression_ro_2.csprojFalling back to patching base and 3-way merge...Auto-merging src/coreclr/jit/compiler.hppCONFLICT (content): Merge conflict in src/coreclr/jit/compiler.hppCONFLICT (modify/delete): src/tests/JIT/Regression/Regression_ro_2.csproj deleted in HEAD and modified in ignore PhiArgs without real preds. Version ignore PhiArgs without real preds of src/tests/JIT/Regression/Regression_ro_2.csproj left in tree.error: Failed to merge in the changes.hint: Use 'git am --show-current-patch=diff' to see the failed patchhint: When you have resolved this problem, run "git am --continue".hint: If you prefer to skip this patch, run "git am --skip" instead.hint: To restore the original branch and stop patching, run "git am --abort".hint: Disable this message with "git config set advice.mergeConflict false"Patch failed at 0001 ignore PhiArgs without real predsError: The process '/usr/bin/git' failed with exit code 128

Link to workflow output

@github-actionsgithub-actionsBot locked as resolved and limited conversation to collaborators Jul 14, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclrCLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JIT: True branch not executed

4 participants

@EgorBo@AndyAyersMS@dhartglassMSFT