JDK-8203915 : Induction variable of over-unrolled loop conflicts with range checks
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9,10,11
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2018-05-29
  • Updated: 2020-02-28
  • Resolved: 2018-06-14
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11
11 b19Fixed
Related Reports
Cloners :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
When running the h2 DaCapo benchmark with -XX:-TieredCompilation -Xcomp, it complains that the AD file is "bad", like this:

Default case invoked for: 
   opcode  = 101, "Con"
o1      Con     === o0  [[]]  #top

--N: o1 Con     === o0  [[]]  #top


Failure modes:

#  Internal Error (/oracle/jdk_jdk/open/src/hotspot/share/opto/loopnode.cpp:3806), pid=19752, tid=19761
#  assert(!had_error) failed: bad dominance

Current CompileTask:
C2:  14351 3470    b        compiler.loopopts.TestOverunrolling::test3 (89 bytes)

Stack: [0x00007f15d14f6000,0x00007f15d15f7000],  sp=0x00007f15d15f10c0,  free space=1004k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x19c0d1c]  VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long)+0x18c
V  [libjvm.so+0x19c1caf]  VMError::report_and_die(Thread*, void*, char const*, int, char const*, char const*, __va_list_tag*)+0x2f
V  [libjvm.so+0xbbcffa]  report_vm_error(char const*, int, char const*, char const*, ...)+0x12a
V  [libjvm.so+0x13a2a37]  PhaseIdealLoop::compute_lca_of_uses(Node*, Node*, bool)+0x3d7
V  [libjvm.so+0x13a30e0]  PhaseIdealLoop::build_loop_late_post(Node*)+0x140
V  [libjvm.so+0x13a3823]  PhaseIdealLoop::build_loop_late(VectorSet&, Node_List&, Node_Stack&)+0x113
V  [libjvm.so+0x13a7e54]  PhaseIdealLoop::build_and_optimize(bool, bool)+0x934
V  [libjvm.so+0xb15aa7]  Compile::Optimize()+0xf07
V  [libjvm.so+0xb17130]  Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool, DirectiveSet*)+0x1380
V  [libjvm.so+0x8f7532]  C2Compiler::compile_method(ciEnv*, ciMethod*, int, DirectiveSet*)+0x302
V  [libjvm.so+0xb248a0]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0x3c0
V  [libjvm.so+0xb25589]  CompileBroker::compiler_thread_loop()+0x269
V  [libjvm.so+0x1902f67]  JavaThread::thread_main_inner()+0x287
V  [libjvm.so+0x19031c1]  JavaThread::run()+0x191
V  [libjvm.so+0x15f7f4a]  thread_native_entry(Thread*)+0xfa


#  Internal Error (/oracle/jdk_jdk/open/src/hotspot/share/opto/matcher.cpp:1575), pid=24470, tid=24479
#  assert(false) failed: bad AD file

Current CompileTask:
C2:  14689 3471    b        compiler.loopopts.TestOverunrolling::test5 (56 bytes)

Stack: [0x00007f93b01bd000,0x00007f93b02be000],  sp=0x00007f93b02b8bf0,  free space=1006k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x19c0d1c]  VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long)+0x18c
V  [libjvm.so+0x19c1caf]  VMError::report_and_die(Thread*, void*, char const*, int, char const*, char const*, __va_list_tag*)+0x2f
V  [libjvm.so+0xbbcffa]  report_vm_error(char const*, int, char const*, char const*, ...)+0x12a
V  [libjvm.so+0x1484587]  Matcher::Label_Root(Node const*, State*, Node*, Node const*)+0x717
V  [libjvm.so+0x148412e]  Matcher::Label_Root(Node const*, State*, Node*, Node const*)+0x2be
V  [libjvm.so+0x14847a6]  Matcher::match_tree(Node const*)+0x1b6
V  [libjvm.so+0x1487428]  Matcher::xform(Node*, int)+0xb78
V  [libjvm.so+0x148b894]  Matcher::match()+0xfb4
V  [libjvm.so+0xb12433]  Compile::Code_Gen()+0xc3
V  [libjvm.so+0xb171f1]  Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool, DirectiveSet*)+0x1441
V  [libjvm.so+0x8f7532]  C2Compiler::compile_method(ciEnv*, ciMethod*, int, DirectiveSet*)+0x302
V  [libjvm.so+0xb248a0]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0x3c0
V  [libjvm.so+0xb25589]  CompileBroker::compiler_thread_loop()+0x269
V  [libjvm.so+0x1902f67]  JavaThread::thread_main_inner()+0x287
V  [libjvm.so+0x19031c1]  JavaThread::run()+0x191
V  [libjvm.so+0x15f7f4a]  thread_native_entry(Thread*)+0xfa
Comments
Unfortunately, the fix caused problems. I will back it out and redo with JDK-8205033.
14-06-2018

New webrev: http://cr.openjdk.java.net/~thartmann/8203915/webrev.01/ Incremental: http://cr.openjdk.java.net/~thartmann/8203915/webrev.inc/
13-06-2018

http://cr.openjdk.java.net/~thartmann/8203915/webrev.00/ Summary: The general problem is that a range check predicated loop is over-unrolled such that the type of the loop induction variable is out of the statically known bounds of the array. As a result, the CastII/ConvI2L nodes are replaced by TOP and the memory graph is corrupted because the control path to this dead code is not removed. This is because there are no range checks in the loop but only predicates before the main loop. For example, in TestOverunrolling::test5() we unroll the inner for-loop 16 times because the loop limit 'i' is not statically known. The last iArr access in the unrolled main loop body therefore has the type [6+stride-1, int] with stride = 16 which is out of the statically known array size 8. After vectorization, we crash in the matcher because the vectorized result += ... computation has a TOP memory input. Test3 and test4 trigger the same problem but fail at different stages during compilation. This is very similar to what Roland fixed with skeleton predicates in JDK-8193130. However, this fix only added checks to verify that the initial value of the induction variable is in bounds but not that init+stride-1 is in bounds as well. I've changed the skeleton predicate code to not only add a check for init <u length but also add another copy of the skeleton predicate to before the main loop. Whenever we now unroll the loop and therefore increase the stride, this predicate copy is updated to check init+stride-1 <u length. To prevent early folding of the expression, I left the Opaque1Nodes in (they are removed after loop optimizations).
07-06-2018

I've found a simple test (Test.java) that triggers this crash reliably with JDK 9, 10 and 11. It's another problem with loop over-unrolling. This is very similar to JDK-8193130, not sure yet why skeleton predicates don't help.
01-06-2018

Okay, I can reproduce it before JDK-8200477 with -XX:-UseCountedLoopSafepoints. Also reproduces with JDK 9 and 10.
31-05-2018

This problem was introduced or triggered by JDK-8200477 in JDK 11 b11. It does not reproduce with earlier builds. Steps to reproduce: - Download Dacapo from https://sourceforge.net/projects/dacapobench/files/ - Unpack dacapo-h2.jar and derbyTesting.jar from jar file - Run java -XX:+ReplayCompiles -XX:ReplayDataFile=replay_pid22330.log -XX:+ReplayIgnoreInitErrors -cp dacapo-h2.jar:derbyTesting.jar We fail during matching because the input to a AddReductionVI is constant TOP: o2397 Phi === o2394 o2357 o2377 [[o2377 ]] #int o2377 AddReductionVI === _ o2397 o1 [[o2397 o2402 222 ]]
30-05-2018

ILW = Crash during compilation, reproducible with Dacapo benchmark, disable compilation of affected method or disable superword (-XX:-UseSuperWord) = HMM = P2
30-05-2018