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
8277529: SIGSEGV in C2 CompilerThread Node::rematerialize() compiling Packet::readUnsignedTrint #6670
Conversation
… Packet::readUnsignedTrint
👋 Welcome back chagedorn! A progress list of the required criteria for merging this PR into |
@chhagedorn The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
Webrevs
|
if (is_range_check_if(iff, phase, T_INT, iv, range, offset, scale)) { | ||
if (!invar.is_invariant(range)) { |
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.
First, the fix is reasonable to me.
My only complain is original code flow. If we do return false;
for each check we should the same for is_range_check_if()
check instead of returning false
at the very end you lost logic why it is false
.
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 for your review Vladimir! Good point, I changed that into a direct bailout.
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.
Nice analysis and test. Looks good to me.
@chhagedorn 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 95 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 |
Thanks Tobias for your review! |
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 good to me.
Thanks Roland for your review and the offline discussion about it. I will file an RFE once it is integrated to clean it up in JDK 19. |
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.
Update looks good.
Thanks Vladimir for your review! |
/integrate |
Going to push as commit 01cb2b9.
Your commit was automatically rebased without conflicts. |
@chhagedorn Pushed as commit 01cb2b9. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
This bug was found in internal testing for 17.0.2 after the backport of JDK-8272574. The fix rewires a control input of a split load node through a phi to the same control input as the corresponding memory input into the phi node:
jdk/src/hotspot/share/opto/memnode.cpp
Lines 1629 to 1637 in e002bfe
This can lead to an illegal control input for the new load if
mem->in(i)
is a projection. This situation occurs in the test case:mem->in(i)
is a projection of anArrayCopy
node. Having anArrayCopy
node as control input is unexpected and we later fail with an assertion (in product we crash with a segfault).My initial thought was to just not apply the improved rewiring for memory projections and fall back to the else case on L1636. However, this also does not work as we could then wrongly move a range check out of a loop and creating a cyclic dependency (case described in the review of JDK-8272574) and reproduced with
test2()
where we hit:jdk/src/hotspot/share/opto/loopPredicate.cpp
Lines 777 to 778 in e002bfe
During this analysis I came across the fix for JDK-8146792 which should actually prevent loop predication if we have a data dependency on the projection into a loop. But this does not seem to work correctly as shown in the test case found for JDK-8272574. In the review of JDK-8272574, it was missed that the actual problem could have been traced back to JDK-8146792 and instead we went for an improvement for loads split through phis to not end up with cases supposed to be fixed by JDK-8146972 (which now also causes other problems). But the root problem is still there to be fixed.
I therefore propose to completely undo the fix for JDK-8272574 for now and go for a fix on top of JDK-8146972 to fix JDK-8272574 and also prevent this bug. The assertion code added by JDK-8272574 is still good to have. I suggest to revisit the improved rewiring for loads done with JDK-8272574 in an RFE. I think it should still be beneficial but requires some more careful checking (to avoid the problems reported in this bug).
Explanation of JDK-8272574 with regard to JDK-8146972 (covered by
test2-5()
):When deciding if we can apply loop predication to a check inside the loop, we call
IdealLoopTree::is_range_check()
. This method callsPhaseIdealLoop::is_scaled_iv_plus_offset()
which can create new nodes for the offset:jdk/src/hotspot/share/opto/loopTransform.cpp
Lines 2586 to 2588 in b79554b
get_ctrl()
of these new nodes could also be the incoming projection into a loop. But these nodes are not marked as non-loop-invariant as done for the other nodes inInvariant::Invariant()
:jdk/src/hotspot/share/opto/loopPredicate.cpp
Lines 663 to 667 in b79554b
The proposed fix keeps track when above code was applied (
data_dependency_on
is set) and does an additional checking forget_ctrl()
accordingly if a new node was created for the offset inPhaseIdealLoop::is_scaled_iv_plus_offset()
. This should be fine as we are not using the newly createdoffset
node anymore after doing that check.In discussions with Roland, we think that we should revisit this fix and the fix of JDK-8146972 and clean them up to directly do the invariant checks in
compute_invariance()/visit()
without special handling in the constructor. But given the deadline of 17.0.2 and the fork soon coming up for 18, we think it's the most safe way to go with the proposed fix - if others agree.Thanks,
Christian
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/6670/head:pull/6670
$ git checkout pull/6670
Update a local copy of the PR:
$ git checkout pull/6670
$ git pull https://git.openjdk.java.net/jdk pull/6670/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 6670
View PR using the GUI difftool:
$ git pr show -t 6670
Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/6670.diff