Skip to content

JIT: tolerate malformed IL when counting block successors #83676

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 22, 2023

Conversation

AndyAyersMS
Copy link
Member

If we run synthesis, we may now invoke BasicBlock::NumSucc before we've detected some cases of invalid IL, In particular an endfinally that is not within a finally (this gets detected during importation).

Tolerate this by reporting that an endfinally with no handler index has no successors.

Fixes #83674.

If we run synthesis, we may now invoke `BasicBlock::NumSucc` before we've
detected some cases of invalid IL, In particular an endfinally that is not
within a finally (this gets detected during importation).

Tolerate this by reporting that an endfinally with no handler index has no
successors.

Fixes dotnet#83674.
@ghost ghost assigned AndyAyersMS Mar 20, 2023
@ghost ghost added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Mar 20, 2023
@ghost
Copy link

ghost commented Mar 20, 2023

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

Issue Details

If we run synthesis, we may now invoke BasicBlock::NumSucc before we've detected some cases of invalid IL, In particular an endfinally that is not within a finally (this gets detected during importation).

Tolerate this by reporting that an endfinally with no handler index has no successors.

Fixes #83674.

Author: AndyAyersMS
Assignees: AndyAyersMS
Labels:

area-CodeGen-coreclr

Milestone: -

@AndyAyersMS
Copy link
Member Author

@BruceForstall PTAL
cc @dotnet/jit-contrib (feel free to poach the review, it is a simple change)

@AndyAyersMS
Copy link
Member Author

Failure looks like an instance of #82771 and is not related.

{
return 0;
}

Copy link
Member

Choose a reason for hiding this comment

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

Would it be feasible to badcode on something like this earlier so we could have a nicer invariant on the data structures, making it simpler to work with this?

What about the other NumSucc variant?

Copy link
Member Author

Choose a reason for hiding this comment

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

Would it be feasible to badcode on something like this earlier

I think in this case we can probably detect it earlier, when we're building the flow graph. I can look into this.

What about the other NumSucc variant?

BBJ_EHFINALLYRET is handled differently in the "simple" variant, since it takes some work to figure out where control goes when it leaves a finally; we don't represent this flow via graph edges.

It turns out that synthesis runs so early that the algorithm the complex variant uses won't work anyways (the relevant blocks are created by our friend impImportLeave which as the name implies happens in the importer), but synthesis wants the complex variant's behavior for other BBJ kinds.

Copy link
Member Author

Choose a reason for hiding this comment

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

Would it be feasible to badcode on something like this earlier

I think in this case we can probably detect it earlier, when we're building the flow graph. I can look into this.

In the failing test case we have an endfinally in an inlinee. We could catch this earlier by calling fgCheckBasicBlockControlFlow before returning from fgMakeBasicBlocks for inlinees and for methods with no EH clauses.

But that seems like overkill for this case; we know immediately when we see the IL opcode that things are bad, since the method has no EH clauses. But thanks to the issue I was trying to resolve in #83622 we pollute the inlinee with the root method's EH table, so the check for "has no EH clauses" is not quite as simple as checking info.compXcptnsCount == 0.

So (assuming I don't merge #83622 because of the TP impact) the check has to be a bit more nuanced: BADCODE if we see an endfinally (or endfilter) and we're the root method and info.compXcptnsCount is zero, or always, if we're an inlinee (thus further deepening the assumption that we won't inline methods with EH).

There is also the possibility that the block with the wayward endfinally is unreachable in which case we might be able to jit the method and just ignore the problematic IL.

So I'm tempted to go with this fix.

Copy link
Member

Choose a reason for hiding this comment

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

Ok, sounds good. Thanks for looking.

@AndyAyersMS AndyAyersMS merged commit 1d9c93f into dotnet:main Mar 22, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Apr 22, 2023
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.

runtime-coreclr pgostress: failures with synthetic PGO
2 participants