-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8340214: C2 compilation asserts with "no node with a side effect" in PhaseIdealLoop::try_sink_out_of_loop #21303
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
Conversation
|
👋 Welcome back roland! A progress list of the required criteria for merging this PR into |
|
@rwestrel This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be: You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 69 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
|
@rwestrel |
Webrevs
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks reasonable.
This assert has proven to be quite valuable to find problems in the memory graph that we would otherwise miss. It was also one of the few assert that triggered when having a corrupted graph due to missing Assertion Predicates. I'm wondering if we need more such memory graph checks in general. Anyway, that's just a thought for some future RFE.
test/hotspot/jtreg/compiler/types/TestBadMemSliceWithInterfaces.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks reasonable to me. I submitted testing and will report back once it passed.
As further clean up, maybe we want to drop the slice argument to GraphKit::make_load() and GraphKit::store_to_memory() (and to their callers) given it's redundant with the address type and error prone.
Yes, let's do that. Please file a starter RFE.
src/hotspot/share/opto/compile.cpp
Outdated
| } else { | ||
| tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, nullptr, offset); | ||
| } | ||
| assert(tj->offset() == offset, "not change to offset expected"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| assert(tj->offset() == offset, "not change to offset expected"); | |
| assert(tj->offset() == offset, "no change to offset expected"); |
| if (xk && ik->equals(canonical_holder)) { | ||
| assert(tj == TypeInstPtr::make(to->ptr(), canonical_holder, is_known_inst, nullptr, offset, instance_id), "exact type should be canonical type"); | ||
| } else { | ||
| assert(xk || !is_known_inst, "Known instance should be exact type"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a comment here and explain the two cases when we create a new type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in new commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
…s.java Co-authored-by: Christian Hagedorn <christian.hagedorn@oracle.com>
Co-authored-by: Christian Hagedorn <christian.hagedorn@oracle.com>
|
| if (xk && ik->equals(canonical_holder)) { | ||
| assert(tj == TypeInstPtr::make(to->ptr(), canonical_holder, is_known_inst, nullptr, offset, instance_id), "exact type should be canonical type"); | ||
| } else { | ||
| assert(xk || !is_known_inst, "Known instance should be exact type"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still good, one more minor thing.
test/hotspot/jtreg/compiler/types/TestBadMemSliceWithInterfaces.java
Outdated
Show resolved
Hide resolved
…s.java Co-authored-by: Christian Hagedorn <christian.hagedorn@oracle.com>
|
@TobiHartmann Do you have an update on testing? |
|
Sorry, that slipped through. Testing looked good. Let me re-run some quick testing with the latest updates. |
|
All testing passed. |
|
@TobiHartmann @chhagedorn thanks for the reviews. |
|
/integrate |
|
Going to push as commit ff2f39f.
Your commit was automatically rebased without conflicts. |
The patch includes 2 test cases for this: test1() causes the assert
failure in the bug description, test2() causes an incorrect execution
where a load floats above a store that it should be dependent on.
In the test cases,
fieldis accessed on objectaof typeA. Whenthe field is accessed, the type that c2 has for
aisAwithinterface
I. The holder of the field is classAwhich implementsno interface. The reason the type of
aand the type of the holderare slightly different is because
ais the result of a merge ofobjects of subclasses
BandCwhich implementsI.The root cause of the bug is that
Compile::flatten_alias_type()doesn't change
A+ interfaceIintoA, the actual holder of thefield. So
fieldinA+ interfaceIandfieldinAgetdifferent slices which is wrong. At parse time, the logic that creates
the
Storenode uses:to compute the slice which is the slice for
fieldinA. So theslice used at parse time is the right one but during igvn, when the
slice is computed from the input address, a different slice (the one
for
A+ interfaceI) is used. That causes load/store nodes whenthey are processed by igvn to use the wrong memory state.
In
Compile::flatten_alias_type():only flattens the type if it's not the canonical holder but it should
test that the type doesn't implement interfaces that the canonical
holder doesn't. To keep the logic simple, the fix I propose creates a
new type whenever there's a chance that a type implements extra
interfaces (the type is not exact).
I also added asserts in
GraphKit::make_load()andGraphKit::store_to_memory()to make sure the slice that is passedand the address type agree. Those asserts fire with the new test
cases. When running testing, I found that they also catch a few cases
in
library_call.cppwhere an incorrect slice is passed.As further clean up, maybe we want to drop the slice argument to
GraphKit::make_load()andGraphKit::store_to_memory()(and totheir callers) given it's redundant with the address type and error
prone.
/cc hotspot-compiler
Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/21303/head:pull/21303$ git checkout pull/21303Update a local copy of the PR:
$ git checkout pull/21303$ git pull https://git.openjdk.org/jdk.git pull/21303/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 21303View PR using the GUI difftool:
$ git pr show -t 21303Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/21303.diff
Webrev
Link to Webrev Comment