RFR(XS): 8229855: C2 fails with assert(false) failed: bad AD file
Tobias Hartmann
tobias.hartmann at oracle.com
Tue Jan 7 16:27:20 UTC 2020
Hi,
please review the following patch:
https://bugs.openjdk.java.net/browse/JDK-8229855
http://cr.openjdk.java.net/~thartmann/8229855/webrev.00/
For the switch statement in TestJumpTable.java, C2 creates the following binary search tree with a
jump table at (*):
if (key_val > 45) {
if (key_val != 60) {
if (key_val <= 60) {
(*)
} else {
[...]
}
} else {
[...]
}
} else {
[...]
}
The jump table at (*) handles the following key_val ranges: {46..50}, {51}, {52..59}.
Parse::jump_switch_ranges -> Parse::create_jump_tables adds a CastII to narrow the type of key_val
to type int:46..59 (type int:0..13 after normalizing to zero):
http://hg.openjdk.java.net/jdk/jdk/file/44cb1f517839/src/hotspot/share/opto/parse2.cpp#l884
Now after some rounds of loop unrolling, key_val is known to be int:60..260 (normalized to
int:14..214) in one of the loop bodies. As a result, the narrow CastII node is replaced by TOP and
we crash in the matcher because the JumpNode user didn't go away.
The problem is that the key_val != 60 && key_val <= 60 combination is *not* found to be always false
if key_val becomes known as int:60..260 because C2's type system does not narrow the type after the
first check. The fix is to simply strengthen the second check to ensure that both control and data
paths die consistently.
I would like to push this simple fix into JDK 14 and follow-up in JDK 15 with an enhancement that
adds a general optimization for such integer checks:
https://bugs.openjdk.java.net/browse/JDK-8236721
I've quickly hacked a prototype that shows promising results (and would also fix this issue):
http://cr.openjdk.java.net/~thartmann/8236721/webrev.00/
Thanks,
Tobias
More information about the hotspot-compiler-dev
mailing list