RFR: 8350579: Remove Template Assertion Predicates belonging to a loop once it is folded away [v2]

Emanuel Peter epeter at openjdk.org
Mon Mar 24 12:37:22 UTC 2025


On Wed, 19 Mar 2025 14:36:29 GMT, Christian Hagedorn <chagedorn at openjdk.org> wrote:

>> The patch fixes the issue of creating an Initialized Assertion Predicate at a loop X from a Template Assertion Predicate that was originally created for a loop Y. Using the unrelated loop values from loop Y for the Initialized Assertion Predicate will let it fail during runtime and we execute a `halt` instruction. This was originally reported with [JDK-8305428](https://bugs.openjdk.org/browse/JDK-8305428).
>> 
>> Note that most of the line changes are from new tests.
>> 
>> ### The Problem
>> There are multiple test cases triggering the same problem. In the following, when referring to "the test case", I'm referring to `testTemplateAssertionPredicateNotRemovedHalt()` which was written from scratch and contains more detailed comments explaining how we end up with executing a `Halt` node in more details. 
>> 
>> #### An Inner Loop without Parse Predicates
>> The graph in `testTemplateAssertionPredicateNotRemovedHalt()` looks like this after creating `LoopNodes` for the outer `for` and inner `while (true)` loop:
>> 
>> ![image](https://github.com/user-attachments/assets/7ac60e35-0b7e-4f04-b9dd-6eb8c8654a15) 
>> 
>> We only have Parse Predicates for the outer loop. Why? 
>> 
>> Before beautify loop, we have the following region which merges multiple backedges - the one from the `for` loop and the one from the `while (true)` loop:
>> 
>> ![image](https://github.com/user-attachments/assets/7895161d-5ac1-46d6-93fe-5ab90ef24ab9)
>> 
>> In `IdealLoopTree::merge_many_backedges()`, we notice that the hottest backedge is hot enough such that it is worth to have a separate merge point region for the inner and outer loop. We set everything up and eventually in  `IdealLoopTree::split_outer_loop()`, we create a second `LoopNode`.
>> 
>> For this inner `LoopNode`, we cannot set up `Parse Predicates` with the same UCTs as used for the outer loop. It would be incorrect when taking the trap to re-execute the inner and outer loop again while having already executed some of the outer loop's iterations. Thus, we get the graph shape with back-to-back `LoopNodes` as shown above.
>>  
>> #### Predicates from a Folded Loop End up at Another Loop
>> As described in the previous section, we have an inner and outer `LoopNode` while the inner does not have Parse Predicates. In a series of events (see test case comments for more details), we first hoist a range check out of the outer loop during Loop Predication with a Template Assertion Predicate. Then, we fold the outer loop away because we find that it is...
>
> Christian Hagedorn has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains six commits:
> 
>  - Small things
>  - Fix test comments
>  - New approach: Marking unrelated Template Assertion Predicates outside of IGVN by storing a reference to the loop it originally was created for.
>  - Merge branch 'master' into JDK-8350579
>  - Revert fix completely
>  - 8350579: Remove Template Assertion Predicates belonging to a
>     loop once it is folded away during IGVN

Nice work @chhagedorn !

src/hotspot/share/opto/loopTransform.cpp line 1706:

> 1704:   // Compute the value of the loop induction variable at the end of the
> 1705:   // first iteration of the unrolled loop: init + new_stride_con - init_inc
> 1706:   int unrolled_stride_con = stride_con_before_unroll * 2;

Could we assert that `stride_con_before_unroll == main_loop_head->stride_con()`?

src/hotspot/share/opto/predicates.cpp line 1267:

> 1265:       template_assertion_predicate.opaque_node()->mark_useful();
> 1266:     }
> 1267:   }

I'm not sure if it makes to split this into two methods, but that's subjective 😅 

It seems to me that the code in `visit` is an optimization for what happens in `mark_template_useful_if_matching_loop`, and does not really make sense on its own.

-------------

Marked as reviewed by epeter (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/23823#pullrequestreview-2710199784
PR Review Comment: https://git.openjdk.org/jdk/pull/23823#discussion_r2010077164
PR Review Comment: https://git.openjdk.org/jdk/pull/23823#discussion_r2010092615


More information about the hotspot-compiler-dev mailing list