-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
8335747: C2: fix overflow case for LoopLimit with constant inputs #23024
Conversation
👋 Welcome back epeter! A progress list of the required criteria for merging this PR into |
@eme64 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 38 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 |
May be we check it to not touch this loop until we fully unroll it (for small number of iterations) |
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.
Good.
I think you are mistaken here,
In this case, can we return |
Yikes, I think you are right. Still, the lowering happens only after post-loop-opts phase, so the Value optimization could have constant folded it in most cases by then. I hope that is good enough. The alternative is to test-run
Hmm, I'm not sure. I'm a little worried about the if here: |
You are right, but I believe the resulting expansion will constant fold regardless. So, why do we need to reject constant folding of the |
@merykitty You are probably right, we could probably just constant-fold in We could investigate this in a follow-up RFE, what do you think? |
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, please go ahead.
Thanks @merykitty @vnkozlov for the reviews! |
Going to push as commit f0af830.
Your commit was automatically rebased without conflicts. |
LoopLimitNode::Value
tries to constant-fold when it has constant inputs. However, there can be an overflow in the int-computation, but we check for it withif (final_con == (jlong)final_int) {
and do not constant fold in that case.However, there was an
assert
that checked that such an overflow would never be encountered. We already had to make an exception for this assert during PhaseCCP with JDK-8309266.Why did we not hit this assert before?
LoopLimitNode
needs to have constant inputs. We used to assume that if the constants would lead to an overflow, then the loop-limit-check would also get similar constants, and detect thatlimit <= max_int-stride
does not hold, and it would constant-fold away the loop, together with theLoopLimitNode
.But now we found a second case:
jdk/src/hotspot/share/opto/loopnode.cpp
Lines 2555 to 2563 in d93d1a3
In
PhaseIdealLoop::split_thru_phi
, we temporarily split theLoopLimitNode
through the phi, generating a newLoopLimitNode
for each branch of thephi
. We then callValue
on it to see if that leads us to constant fold one of the branches, which would be considered a "win".jdk/src/hotspot/share/opto/loopopts.cpp
Lines 87 to 105 in d93d1a3
In the regression test, we have this example:
jdk/test/hotspot/jtreg/compiler/loopopts/TestLoopLimitOverflowDuringSplitThruPhi.java
Lines 44 to 69 in d93d1a3
We generate a temporary clone of
LoopLimitNode(init=0, limit=x, stride=4)
(would not constant fold because of variablex = Phi(1000, 2147483647)
), which happens to beLoopLimitNode(init=0, limit=2147483647, stride=4)
. We evaluateValue
on this temporary clone, and hit the overflow case.Why is it ok to just remove the assert and allow
LoopLimitNode
to overflow?We still have the loop limit check, which checks that
limit <= max_int-stride
, and this means we would never enter the loop if we took thePhi
branch that led to the overflow.I could not just remove the assert, because in
LoopLimitNode::Ideal
we have this (strange?) check that does not optimize theLoopLimitNode
if the inputs are constants:The assumption seems to be that we want
Value
to do the constant folding here - but of course we did not constant-fold because we had detected the overflow inValue
. Not optimizing further here has a unfortunate consequence: on platforms that do not haveLoopLimit
implemented in the backend directly, we would have "lowered" theLoopLimit
further down intoConvI2L, SubL, AddL, DivL, ConvL2I ...
nodes. With this check, we do never lower it, and end up with a "bad AD", i.e. compilation bailout in product.I think this check can reasonably be removed, because
Value
should be called beforeIdeal
anyway, and so if we can constand fold because of constant inputs, we would have already done so.Note, that the lowering is delayed until
post_loop_opts_phase
, but we never didrecord_for_post_loop_opts_igvn
, and so it was not guaranteed that we actually ever processed theLoopLimitNode
again, which would mean we got "bad AD" again, i.e. compilation bailout in product.Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/23024/head:pull/23024
$ git checkout pull/23024
Update a local copy of the PR:
$ git checkout pull/23024
$ git pull https://git.openjdk.org/jdk.git pull/23024/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 23024
View PR using the GUI difftool:
$ git pr show -t 23024
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/23024.diff
Using Webrev
Link to Webrev Comment