Skip to content

Conversation

@jakobbotsch
Copy link
Member

DataFlow::ForwardAnalysis used a worklist based algorithm where it kept visiting successor blocks as long as information was being propagated until closure. However, this successor-based visit was using regular successors only, which does not account for EH second-pass flow.

This was not generally a correctness problem as the only users of this class are CSE and assertion prop, and neither of them have a correctness requirement of propagating facts along filter -> finally/fault edges, but the imprecision in the modelling could result in disagreements in reachability with the DFS visit.

Concretely we could end up with CSE's availability analysis finding that a nested finally/fault block was unreachable (because its corresponding try-entry was unreachable), while the DFS visit considered it reachable due to a spurious filter predecessor. This mismatch meant that the handler was never visited by the CSE dataflow which would result in all CSEs in some of the handler blocks being marked as available. We would then end up creating a use in one of these blocks, which SSA updating would not be able to find a corresponding def for.

Fix the situation by switching DataFlow::ForwardAnalysis to compute a DFS tree and computing the closure based on its RPO.

Fix #111345

`DataFlow::ForwardAnalysis` used a worklist based algorithm where it
kept visiting successor blocks as long as information was being
propagated until closure. However, this successor-based visit was using
regular successors only, which does not account for EH second-pass flow.

This was not generally a correctness problem as the only users of this
class are CSE and assertion prop, and neither of them have a correctness
requirement of propagating facts along filter -> finally/fault edges,
but the imprecision in the modelling could result in disagreements in
reachability with the DFS visit.

Concretely we could end up with CSE's availability analysis finding that
a nested finally/fault block was unreachable (because its corresponding
try-entry was unreachable), while the DFS visit considered it reachable
due to a spurious filter predecessor. This mismatch meant that the
handler was never visited by the CSE dataflow which would result in all
CSEs in some of the handler blocks being marked as available. We would
then end up creating a use in one of these blocks, which SSA updating
would not be able to find a corresponding def for.

Fix the situation by switching `DataFlow::ForwardAnalysis` to compute a
DFS tree and computing the closure based on its RPO.

Fix dotnet#111345
@jakobbotsch
Copy link
Member Author

/azp run runtime-coreclr superpmi-diffs

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jakobbotsch jakobbotsch marked this pull request as ready for review January 23, 2025 12:45
@jakobbotsch
Copy link
Member Author

cc @dotnet/jit-contrib PTAL @AndyAyersMS

No diffs except some nice TP improvements.

Copy link
Contributor

@kunalspathak kunalspathak left a comment

Choose a reason for hiding this comment

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

LGTM

@jakobbotsch jakobbotsch merged commit 7e8f0a5 into dotnet:main Jan 23, 2025
111 checks passed
@jakobbotsch jakobbotsch deleted the fix-111345-2 branch January 23, 2025 20:20
@github-actions github-actions bot locked and limited conversation to collaborators Feb 23, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-CodeGen-coreclr CLR 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.

Assertion failed '!"Found use without any def"' during 'Optimize Valnum CSEs'

2 participants