8360510: C2: Template Assertion Predicates are not cloned to the inner counted loop with -XX:+StressDuplicateBackedge #28389
+143
−4
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Strong Connection between Template Assertion Predicate and Counted Loop
In JDK-8350579, we fixed the issue that a Template Assertion Predicate for a folded loop A could end up at another loop B. We then created an Initialized Assertion Predicate at loop B from the template of loop A and used the values from the already folded, completely unrelated loop A . As a result, we crashed with a halt because loop B violated the predicate with the wrong values. As a fix, we established a strong connection between Template Assertion Predicates and their associated loop node by adding a direct link from
OpaqueTemplateAssertionPredicate->CountedLoop.Maintaining this Property
In
PhaseIdealLoop::eliminate_useless_predicates(), we walk through all counted loops and only keep thoseOpaqueTemplateAssertionPredicatenodes that can be found from the loop heads and are actually meant for this loop (using the strong connection):jdk/src/hotspot/share/opto/predicates.cpp
Lines 1245 to 1249 in d2926df
All other opaque nodes are removed.
Additional Verification for Useless
OpaqueTemplateAssertionPredicateNodesAs an additional verification for
OpaqueTemplateAssertionPredicatenodes that are found to be useless ineliminate_useless_predicates(), we check that in this case theCountedLoopis really dead (otherwise, we should have found theOpaqueTemplateAssertionPredicatein our walks through all loop):jdk/src/hotspot/share/opto/predicates.cpp
Lines 1294 to 1301 in d2926df
Violating the Additional Verification with
-XX:+StressLoopBackedgeIn
PhaseIdealLoop::duplicate_loop_backedge(), we convert a loop with a merge point into two loops which should enable us to transform the new inner loop into a counted loop. This only makes sense for aLoopthat is not a counted loop, yet. However, to stress the transformation, we can also run with-XX:+StressDuplicateBackedgethat also transforms a counted loop into an inner and an outer loop. This is a problem when we have Template Assertion Predicates above a counted loop to be stressed:After duplicate backedge, the Template Assertion Predicates are now at the outer non-counted
Loop:In
eliminate_useless_predicates(), we then no longer find these Template Assertion Predicates when walking up from275 CountedLoop. But since the counted loop is still in the graph, the additional verification above fails when checking that a useless Template Assertion Predicate is associated with a dead counted loop - which is not the case.Solution
The solution I propose is to clone the Template Assertion Predicates to the inner counted loop. This can be guarded with an
ifdef ASSERTbecause it can only happen withStressLoopBackedgewhich is a develop flag. This is straight forward and solves this "opaque <-> counted loop" mismatching problem.Additional Changes
TestAssertionPredicates.javawas no longer working (i.e. disablingTemplateAssertionPredicate::rewire_loop_data_dependencies()did not crash). It only triggers when running with ZGC (i.e. produce a crash when disablingrewire_loop_data_dependencies()). I added an additional jtreg block with that flag setup.ifdef ASSERTblock for some code that is only executed forStressDuplicateBackedge.-XX:-StressDuplicateBackedgeand once with. In the latter run, I found thatTestVerifyLoopOptimizationsHitsMemLimit.javahit the memory limit. This seems expected since we create more loop nodes which results in more verification work. The test already uses quite some memory when run withVerifyLoopOptimizations. We now add some more on top which will reach the limit of100Mset for the test. I propose to just disable this test withStressDuplicateBackedge. Note that this also fails before this patch.Thanks,
Christian
Progress
Issue
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/28389/head:pull/28389$ git checkout pull/28389Update a local copy of the PR:
$ git checkout pull/28389$ git pull https://git.openjdk.org/jdk.git pull/28389/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 28389View PR using the GUI difftool:
$ git pr show -t 28389Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/28389.diff
Using Webrev
Link to Webrev Comment