-
Notifications
You must be signed in to change notification settings - Fork 6.2k
8275610: C2: Object field load floats above its null check resulting in a segfault #6701
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 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. |
vnkozlov
left a comment
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.
I agree with bailout for now and proper fix it later.
|
@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 279 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 Vladimir for your review! |
rwestrel
left a comment
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! |
|
/integrate |
|
Going to push as commit 7c6f57f.
Your commit was automatically rebased without conflicts. |
|
@chhagedorn Pushed as commit 7c6f57f. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
In the test case, a field load of an object floats above the object null check due to a
CastPPthat gets separated from its null checkIfnode. C2 then schedules the field load before the object null check which results in a segfault.The problem can be traced back to the elimination of identical back-to-back ifs (JDK-8143542). This is done in split-if where we detect identical back-to-back ifs in
PhaseIdealLoop::identical_backtoback_ifs(). We then replace the boolean node of the dominatedIfby a phi to use the split-if optimization to nicely fold away the dominatedIflater in IGVN. This, however, does not update any data nodes that were dependent on the dominatedIfprojections.In the test case, we have the following graph right before splitting
313 If(NC 2) through190 Region:313 Ifis dominated by the identical (= both share308 Bool)309 If(NC 1). The bool input for313 Ifis replaced by a phi and the split-if optimization is applied. However, the data nodes dependent on the out projections of the dominated313 If(261 CastPPin this case) are not processed separately and just end up at the newly inserted regions in split-if. In the test case, we get the following graph where261 CastPPends up at the new334 Region:Loopopts are applied and can remove the
325 CountedLoopand we find that the171 RangeCheck(RC 2) is applied on a constant array index 1.Now at IGVN, the order in which the nodes are processed is important in order to trigger the segfault:
334 Regionwith332 Ifand333 Ifare removed because of the special split-if setup we used to remove the identical313 If. The control input of261 CastPPis therefore updated to172 IfTrue.RangeCheck::Ideal()for171 RangeCheckfinds that305 RangeCheck(RC 1) already covers it and we remove171 RangeCheck. In this process, we rewire261 CastPPto the dominating305 RangeCheckand we have the following graph:261 CastPP- and also the field263 LoadI- have now306 IfFalseas early control. GCM is then scheduling263 LoadIbefore the null check309 Ifand we get a segfault.An easy fix is not straight forward. What we actually would want to do is rewiring
261 CastPPfrom334 Regionto311 IfTruein the second graph after split-if to not separate it from the null check. But that's not possible because we would create a bad graph: The early control311 IfTrueof261 CastPPdoes not dominate its late control further down after334 Regionbecause of the not yet removed334 Region. We would need to already clean the regions up and then do the rewiring. But then the question arises why to use the split-if optimization in the first place when we do not want to rely on IGVN to clean it up.I therefore suggest to go with an easy bailout fix for JDK 18 where we do not apply this identical back-to-back if removal optimization if there are data dependencies and rework this in an RFE for JDK 19. Roland already has some ideas how to do that.
I ran some standard benchmarks and did not see any performance regressions with this fix.
Thanks,
Christian
Progress
Issue
Reviewers
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/6701/head:pull/6701$ git checkout pull/6701Update a local copy of the PR:
$ git checkout pull/6701$ git pull https://git.openjdk.java.net/jdk pull/6701/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 6701View PR using the GUI difftool:
$ git pr show -t 6701Using diff file
Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/6701.diff