| JDK 11 | JDK 17 | JDK 19 |
|---|---|---|
| 11.0.17-oracleFixed | 17.0.5-oracleFixed | 19 b24Fixed |
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
Similarly to JDK-8279622, a node marked as a reduction is hoisted out of its original reduction loop into an outer loop that is not marked as a reduction. The assertion introduced in JDK-8279622 catches this inconsistency and fails. Unlike JDK-8279622 though, the inconsistent reduction marking in this case is not fatal, in that it would not lead to a miscompilation should the assertion be disabled. This is because the inconsistently marked loop(s) contains safepoints, which inhibits SLP vectorization.
HOW TO REPRODUCE
$ javac Test.java FuzzerUtils.java
$ java Test
# Internal Error (/home/roland/jdk-jdk/src/hotspot/share/opto/superword.cpp:113), pid=4077494, tid=4077507
# assert(!lpt->has_reduction_nodes() || cl->is_reduction_loop()) failed: non-reduction loop contains reduction nodes
#
# JRE version: OpenJDK Runtime Environment (19.0) (fastdebug build 19-internal-adhoc.roland.jdk-jdk)
# Java VM: OpenJDK 64-Bit Server VM (fastdebug 19-internal-adhoc.roland.jdk-jdk, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x1a3cb04] SuperWord::transform_loop(IdealLoopTree*, bool)+0x424
FAILURE ANALYSIS
The node corresponding to (acc += j) is marked as a reduction together with its (inner) loop:
int i = 0, acc = 0;
do {
int j = 0;
do { // inner loop marked as a reduction
if (b) {
acc += j; // node marked as a reduction
}
j++;
} while (j < 5);
i++;
} while (i < 100);
return acc;
After unrolling and constant-folding the inner loop (b is always true), the node formerly corresponding to (acc += j), and now corresponding to (acc += 10), is hoisted into the outer loop, which is not marked as a reduction. This creates an inconsistent state that is later caught by the failing assertion:
int i = 0, acc = 0;
do {
acc += 10; // node marked as a reduction (inconsistent, outer loop is not marked as a reduction)
i++;
} while (i < 100);
return acc;
|