RFR: 8323972: C2 compilation fails with assert(!x->as_Loop()->is_loop_nest_inner_loop()) failed: loop was transformed
Emanuel Peter
epeter at openjdk.org
Tue Mar 12 17:45:14 UTC 2024
On Thu, 22 Feb 2024 14:36:52 GMT, Roland Westrelin <roland at openjdk.org> wrote:
> Long counted loop are transformed into a loop nest of 2 "regular"
> loops and in a subsequent loop opts round, the inner loop is
> transformed into a counted loop. The limit for the inner loop is set,
> when the loop nest is created, so it's expected there's no need for a
> loop limit check when the counted loop is created. The assert fires
> because, when the counted loop is created, it is found that it needs a
> loop limit check. The reason for that is that the limit is
> transformed, between nest creation and counted loop creation, in a way
> that the range of values of the inner loop's limit becomes
> unknown. The limit when the nest is created is:
>
>
> 111 ConL === 0 [[ 112 ]] #long:-9223372034707292158
> 106 Phi === 105 20 94 [[ 112 ]] #long:9223372034707292160..9223372034707292164:www !orig=72 !jvms: TestInaccurateInnerLoopLimit::test @ bci:12 (line 40)
> 112 AddL === _ 106 111 [[ 122 ]] !orig=[110]
> 122 ConvL2I === _ 112 [[ ]] #int
>
>
> The type of 122 is `2..6` but it is then transformed to:
>
>
> 106 Phi === 105 20 154 [[ 191 130 137 ]] #long:9223372034707292160..9223372034707292164:www !orig=[72] !jvms: TestInaccurateInnerLoopLimit::test @ bci:12 (line 40)
> 191 ConvL2I === _ 106 [[ 196 ]] #int
> 195 ConI === 0 [[ 196 ]] #int:max-1
> 196 SubI === _ 195 191 [[ 201 127 ]] !orig=[123]
>
>
> That is the `(ConvL2I (AddL ...))` is transformed into a `(SubI
> (ConvL2I ))`. `ConvL2I` for an input that's out of the int range of
> values returns TypeInt::INT and the bounds of the limit are lost. I
> propose adding a `CastII` after the `ConvL2I` so the range of values
> of the limit doesn't get lost.
Looks reasonable, but these ad-hoc CastII also make me nervous.
What worries me with adding such "Ad-Hoc" CastII nodes is that elsewhere a very similar computation may not have the same tight type. And then you have a tight type somewhere, and a loose type elsewhere. This is how we get the data-flow collapsing and the cfg not folding.
@rwestrel please wait for our testing to complete, I just launched it.
test/hotspot/jtreg/compiler/longcountedloops/TestInaccurateInnerLoopLimit.java line 40:
> 38:
> 39: public static void test() {
> 40: for (long i = 9223372034707292164L; i > 9223372034707292158L; i += -2L) { }
I'm always amazed at how such simple tests can fail. Is there any way we can improve the test coverage for Long loops?
-------------
Marked as reviewed by epeter (Reviewer).
PR Review: https://git.openjdk.org/jdk/pull/17965#pullrequestreview-1931732253
PR Comment: https://git.openjdk.org/jdk/pull/17965#issuecomment-1992220126
PR Review Comment: https://git.openjdk.org/jdk/pull/17965#discussion_r1521846724
More information about the hotspot-compiler-dev
mailing list