RFR: 8325494: C2: Broken graph after not skipping CastII node anymore for Assertion Predicates after JDK-8309902

Christian Hagedorn chagedorn at openjdk.org
Wed Apr 10 14:14:01 UTC 2024


On Wed, 10 Apr 2024 13:41:11 GMT, Roland Westrelin <roland at openjdk.org> wrote:

> After range check elimination, a cast in the main loop becomes top
> because the type of its input (that depends on the iv phi) and the
> type recorded in the cast do not intersect. This is a case that's
> expected to be caught by assert predicates but, in this particular
> case, no assert predicate constant folds.
> 
> The stride for the loop is -2. The iv phi type is `min+1..0`
> 
> As a consequence, the init value for the main loop has type int.
> 
> The range check that causes the issue is for array access:
> 
> lArrFld[i11 + 1] = 6;
> 
> 
> The main loop is unrolled once. The second access in the loop is at
> `i11 - 1` which has type `min..-1`. The range check cast at that
> access becomes top. The assert predicates operates on an init value
> that has the shape:
> 
> 
> (CastII (AddI pre_loop_iv -2) int)
> 
> 
> and type int.
> 
> That `CastII` is inserted by `PhaseIdealLoop::cast_incr_before_loop()`.
> 
> The assert predicate for the first iteration in the main loop is for
> index:
> 
> 
> (AddI (CastII (AddI pre_loop_iv -2) int) 1)
> 
> 
> And for the second:
> 
> 
> (AddI (CastII (AddI pre_loop_iv -2) int) -1)
> 
> 
> Both have type int so the assert predicate can't constant fold.
> 
> I initially fixed this by changing the type of the cast from int to
> the type of the iv phi:
> 
> 
> (AddI (CastII (AddI pre_loop_iv -2) min+1..0) -1)
> 
> 
> That allows the assert predicate for the second iteration to constant
> fold. But I was then worried narrowing the type of the cast would
> causes issues going forward so instead, I propose proceeding as in
> 8282592 and have assert predicates skip over the CastII (that part of
> 8282592 was later undone):
> 
> 
> (AddI (AddI pre_loop_iv -2) 1)
> 
> 
> which allows the assert predicate for the first iteration in the main
> loop to constant fold.
> 
> The change from 8282592 caused issues because we used to narrow the
> type of a cast based on the condition that guards it. That was removed
> by 8319372.

I agree with that. I thought about same now that JDK-8319372 is in.

Two minor comments, otherwise, looks good!

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

> 2017:     // skip over the cast added by PhaseIdealLoop::cast_incr_before_loop() when pre/post/main loops are created because
> 2018:     // it can get in the way of type propagation
> 2019:     assert(((CastIINode*)init)->carry_dependency() && loop_head->skip_assertion_predicates_with_halt() == init->in(0), "casted iv phi from pre loop expected");

You can use `is_CastII()` and `as_CastII()`.

test/hotspot/jtreg/compiler/loopopts/TestAssertPredicateDoesntConstantFold.java line 32:

> 30:  */
> 31: 
> 32: public class TestAssertPredicateDoesntConstantFold {

I suggest to move this test to the other predicate tests in `compiler/predicates`

Nit:
Suggestion:

public class TestAssertionPredicateDoesntConstantFold {

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

Marked as reviewed by chagedorn (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/18724#pullrequestreview-1991798819
PR Review Comment: https://git.openjdk.org/jdk/pull/18724#discussion_r1559506640
PR Review Comment: https://git.openjdk.org/jdk/pull/18724#discussion_r1559508534


More information about the hotspot-compiler-dev mailing list