JDK-8148754 : C2 loop unrolling fails due to unexpected graph shape
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8u112,9
  • Priority: P1
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-02-01
  • Updated: 2020-08-13
  • Resolved: 2016-03-21
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 9 Other
9 b114Fixed openjdk8u272Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Compilation fails in loop optimizations:

#  Internal Error (/scratch/jprt/T/P1/075053.tohartma/s/hotspot/src/share/vm/opto/loopTransform.cpp:1322), pid=4930, tid=5016
#  Error: assert(cmp->Opcode() == Op_CmpI) failed

Current CompileTask:
C2:  29619 2821    b        IeeeRecommendedTests::testFloatBooleanMethods (270 bytes)

Stack: [0x00007f3665d37000,0x00007f3665e38000],  sp=0x00007f3665e32220,  free space=1004k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x13d4b85]  VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long)+0x155;;  VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long)+0x155
V  [libjvm.so+0x13d58bf]  VMError::report_and_die(Thread*, char const*, int, char const*, char const*, __va_list_tag*)+0x2f;;  VMError::report_and_die(Thread*, char const*, int, char const*, char const*, __va_list_tag*)+0x2f
V  [libjvm.so+0x95223d]  report_vm_error(char const*, int, char const*, char const*, ...)+0xdd;;  report_vm_error(char const*, int, char const*, char const*, ...)+0xdd
V  [libjvm.so+0xee88b2]  PhaseIdealLoop::do_unroll(IdealLoopTree*, Node_List&, bool)+0x472;;  PhaseIdealLoop::do_unroll(IdealLoopTree*, Node_List&, bool)+0x472
V  [libjvm.so+0xeed4b5]  IdealLoopTree::iteration_split_impl(PhaseIdealLoop*, Node_List&)+0x225;;  IdealLoopTree::iteration_split_impl(PhaseIdealLoop*, Node_List&)+0x225
V  [libjvm.so+0xeed777]  IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x187;;  IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x187
V  [libjvm.so+0xeed66a]  IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x7a;;  IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x7a
V  [libjvm.so+0xeed66a]  IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x7a;;  IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x7a
V  [libjvm.so+0xeed612]  IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x22;;  IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x22
V  [libjvm.so+0xf0a9b1]  PhaseIdealLoop::build_and_optimize(bool, bool)+0xe91;;  PhaseIdealLoop::build_and_optimize(bool, bool)+0xe91
V  [libjvm.so+0x8c8b63]  Compile::Optimize()+0xd83;;  Compile::Optimize()+0xd83
V  [libjvm.so+0x8ca1fe]  Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool, DirectiveSet*)+0x139e;;  Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool, DirectiveSet*)+0x139e
V  [libjvm.so+0x72fa22]  C2Compiler::compile_method(ciEnv*, ciMethod*, int, DirectiveSet*)+0x2d2;;  C2Compiler::compile_method(ciEnv*, ciMethod*, int, DirectiveSet*)+0x2d2
V  [libjvm.so+0x8d56b4]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0x554;;  CompileBroker::invoke_compiler_on_method(CompileTask*)+0x554
V  [libjvm.so+0x8d6d28]  CompileBroker::compiler_thread_loop()+0x458;;  CompileBroker::compiler_thread_loop()+0x458
V  [libjvm.so+0x133ecc9]  JavaThread::thread_main_inner()+0x1c9;;  JavaThread::thread_main_inner()+0x1c9
V  [libjvm.so+0x133ef26]  JavaThread::run()+0x1c6;;  JavaThread::run()+0x1c6
V  [libjvm.so+0x10c6b52]  java_start(Thread*)+0xd2;;  java_start(Thread*)+0xd2
C  [libpthread.so.0+0x7851]
Comments
Fix Request [8u] This bug is always reproducible with x86 & aarch64 8u fastdebug build running test case located in: http://cr.openjdk.java.net/~fyang/8148754-8u/Test.java http://cr.openjdk.java.net/~fyang/8148754-8u/FuzzerUtils.java Original patch applies cleanly to jdk8u-dev repo. Run full jtreg test with 8u release & fastdebug builds on x86_64-linux-gnu. Also run full jtreg test with 8u release & fastdebug builds on aarch64-linux-gnu.
08-08-2020

verified by nightly testing
26-07-2017

Here are the assumptions the C2 compiler makes about _major_progress: - If _major_progress > 0, more loop optimizations will follow. In this case, (I)GVN graph transformations are limited because the graph shape must be compatible with the upcoming loop optimizations. - If _major_progress == 0, no more loop optimizations will happen. In this case, (I)GVN is allowed to perform extended transformations on the graph because the graph does not have to look as expected by loop optimizations. Here is the sequence of compiler optimizations performed by C2 that leads to Failure #2 from above happens: ccp iterGVN2 Loop optimization iteration #4 Loop optimization iteration #5 ... loop unswitching; creating pre-post-main loop for unrolling; unrolling; split-if; ... Loop optimization iteration #8 No loop optimization performed => _major_progress==false; IGVN performed with _major_progress==false => extended transformations are performed (e.g., Opaque1 nodes are removed); IGVN performs Node::remove_useless_bool() => _major_progress==true => more loop optimizations will be attempted. Loop optimization iteration #9 the IGVN previously performed in iteration #8 simplified the loop body => loop unrolling is attempted again => Crash. Failure #1 is similar: ccp iterGVN2 Loop optimization iteration #4 Loop optimization iteration #5 ... loop unswitching; creating pre-post-main loop for unrolling; unrolling; split-if; ... Loop optimization iteration #7 No loop optimization performed => _major_progress==false; IGVN performed with _major_progress==false => extended transformations are performed (e.g., Opaque1 nodes are removed); IGVN performs Node::remove_useless_bool() => _major_progress==true => more loop optimizations will be attempted. Loop optimization iteration #8 split-if the IGVN that simplifies the loop body Loop optimization iteration #9: loop unrolling is attempted again => Crash.
19-02-2016

In the RFR I referred to examples showing the problems with the graph shape when loop unrolling is attempted. I'll use two different failures as examples in this description. Failure #1: The original failure reported by Tobias # Error: assert(cmp->Opcode() == Op_CmpI) failed Failure #2: The failure I got when restricting the set of compiled methods (as mentioned in my earlier comment) # Error: assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse) failed I've attached the IdealGraphVisualizer output for both failures (failure_1.xml and failure_2.xml). Here is a more detailed analysis of both failures. Failure #1: The compiler crashes when it attempts to unroll '1651 CountedLoopNode'. The entry control of Node 1651 is '2153 IfTrue' that is fed by the chain '2133 If'- '1353 Bool' - '1354 CmpF'. The problem is that '1354 CmpF' is not the type the compiler expects ('CmpI'). Node '1354 CmpF' originates from the loopback control of a different loop that (I assume) was peeled before. The described graph state is for the last 'PhaseIdealLoop Iterations'. Note that in case of Failure #1 an other counted loop node, '921 CountedLoop', has also an unexpected graph shape at its entry control: The entry control is a projection node ('54 Proj') and not a 'IfTrue'/'IfFalse' node. But loop unrolling is not attempted for that loop so no failure appears there. Failure #2: The compiler crashes when it attempts to unroll '1485 CountedLoopNode'. The entry control of Node 1485 is '1129 Region'. That region originates from an earlier split-if optimization. The described graph state is for the last 'PhaseIdealLoop Iterations'. Note that case of Failure #2 the entry control of an other counted loop node, '776 CountedLoop', is a projection node '54 Proj'. Loop unrolling is not attempted for that loop so the compiler does not crash there. The proposed fix solves both Failure #1 and Failure #2. http://cr.openjdk.java.net/~zmajo/8148754/webrev.00/
15-02-2016

If the same test is run with the following compile command directives compileonly,IeeeRecommendedTests::testFloatBooleanMethods compileonly,java.lang.Float::isNaN compileonly,Tests::test dontinline,java.lang.Float::isFinite compileonly,Tests::isUnordered a slightly different failure appears (see attached hs_err_pid10974.log file): # Internal Error (/home/zmajo/Documents/repos/8148754/hotspot/src/share/vm/opto/loopTransform.cpp:1318), pid=10974, tid=10993 # Error: assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse) failed # # JRE version: Java(TM) SE Runtime Environment (9.0) (fastdebug build 9-internal+0-2016-02-04-134742.zmajo.8148754) # Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 9-internal+0-2016-02-04-134742.zmajo.8148754, compiled mode, compressed oops, g1\ gc, linux-amd64) # Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %P" (or dumping to /h\ ome/zmajo/Documents/repos/8148754/bug/test-local/core.10974) # # If you would like to submit a bug report, please visit: # http://bugreport.java.com/bugreport/crash.jsp # --------------- S U M M A R Y ------------ Command Line: -Dseed=9042586825265290657 -Xcomp -XX:-TieredCompilation -XX:+PrintCompilation -XX:CompileCommandFile=cmd-only.file -XX:Lo\ opOptsCount=9 -XX:+TraceLoopOpts -XX:+CIPrintMethodCodes -XX:-UseSuperWord -XX:-RangeCheckElimination -XX:+PrintOpto -XX:+SplitIfBlocks \ -XX:ConditionalMoveLimit=0 -XX:CompilerDirectivesFile=directive.file -XX:+PrintIdealGraph -XX:PrintIdealGraphFile=tmp.xml IeeeRecommende\ dTests Current CompileTask: C2: 3757 28 b IeeeRecommendedTests::testFloatBooleanMethods (238 bytes) Stack: [0x00007f3bff4da000,0x00007f3bff5db000], sp=0x00007f3bff5d5130, free space=1004k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0x12ed092] VMError::report_and_die(int, char const*, char const*, __va_list_tag*, Thread*, unsigned char*, void*, void*, \ char const*, int, unsigned long)+0x182 V [libjvm.so+0x12ede0a] VMError::report_and_die(Thread*, char const*, int, char const*, char const*, __va_list_tag*)+0x4a V [libjvm.so+0x90d77a] report_vm_error(char const*, int, char const*, char const*, ...)+0xea V [libjvm.so+0xe51bc3] PhaseIdealLoop::do_unroll(IdealLoopTree*, Node_List&, bool)+0x4f3 V [libjvm.so+0xe57762] IdealLoopTree::iteration_split_impl(PhaseIdealLoop*, Node_List&)+0x222 V [libjvm.so+0xe579b7] IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x187 V [libjvm.so+0xe578aa] IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x7a V [libjvm.so+0xe578aa] IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x7a V [libjvm.so+0xe57852] IdealLoopTree::iteration_split(PhaseIdealLoop*, Node_List&)+0x22 V [libjvm.so+0xe71448] PhaseIdealLoop::build_and_optimize(bool, bool)+0x1208 V [libjvm.so+0x886a02] Compile::Optimize()+0xea2 V [libjvm.so+0x888166] Compile::Compile(ciEnv*, C2Compiler*, ciMethod*, int, bool, bool, bool, DirectiveSet*)+0x1416 V [libjvm.so+0x71a9d3] C2Compiler::compile_method(ciEnv*, ciMethod*, int, DirectiveSet*)+0x113 V [libjvm.so+0x8921e9] CompileBroker::invoke_compiler_on_method(CompileTask*)+0x459 V [libjvm.so+0x893380] CompileBroker::compiler_thread_loop()+0x540 V [libjvm.so+0x126d509] JavaThread::thread_main_inner()+0x1c9 V [libjvm.so+0x126d846] JavaThread::run()+0x2a6 V [libjvm.so+0x101bc5a] java_start(Thread*)+0xca C [libpthread.so.0+0x8182] start_thread+0xc2 Similar to the originally reported failure, this failure appears also because of an invalid graph shape (the compiler encounters a region node instead of a IfTrue/IfFalse node).
15-02-2016

Seems like we encounter a CmpF instead of a CmpI. Output of cmp->dump(-3); cmp->dump(+3); 1356 CmpF === _ 1357 1357 [[ 1355 1490 ]] !orig=994,780 !jvms: Float::isNaN @ bci:3 Tests::isUnordered @ bci:8 IeeeRecommendedTests::testFloatBooleanMethods @ bci:235 1355 Bool === _ 1356 [[ 1363 2135 1247 2141 ]] [ne] !orig=993,781 !jvms: Float::isNaN @ bci:3 Tests::isUnordered @ bci:8 IeeeRecommendedTests::testFloatBooleanMethods @ bci:235 1490 Bool === _ 1356 [[ 1491 ]] [eq] 1363 If === 1052 1355 [[ 1364 1378 ]] P=0.900000, C=-1.000000 !orig=[1006],782 !jvms: Float::isNaN @ bci:3 Tests::isUnordered @ bci:8 IeeeRecommendedTests::testFloatBooleanMethods @ bci:235 2135 If === 1365 1355 [[ 2136 2137 ]] P=0.999999, C=-1.000000 !orig=[1372],1012,[839] !jvms: Tests::test @ bci:3 IeeeRecommendedTests::testFloatBooleanMethods @ bci:251 1247 If === 1053 1355 [[ 1248 1253 ]] P=0.999999, C=-1.000000 !orig=1157,[1077],1012,[839] !jvms: Tests::test @ bci:3 IeeeRecommendedTests::testFloatBooleanMethods @ bci:251 2141 CMoveI === _ 1355 21 67 [[ 1391 ]] #bool !orig=[1377],[1011],[798] !jvms: Tests::isUnordered @ bci:15 IeeeRecommendedTests::testFloatBooleanMethods @ bci:235 1491 CMoveI === _ 1490 67 21 [[ 1262 ]] #bool !orig=[1252],[1181],[1084],[1011],[798] !jvms: Tests::isUnordered @ bci:15 IeeeRecommendedTests::testFloatBooleanMethods @ bci:235 1364 IfTrue === 1363 [[ 1365 ]] #1 !orig=[1025],783,[888] !jvms: Float::isNaN @ bci:3 Tests::isUnordered @ bci:8 IeeeRecommendedTests::testFloatBooleanMethods @ bci:235 1378 IfFalse === 1363 [[ 1365 ]] #0 !orig=[1007],784,[887] !jvms: Float::isNaN @ bci:3 Tests::isUnordered @ bci:8 IeeeRecommendedTests::testFloatBooleanMethods @ bci:235 2136 IfFalse === 2135 [[ 1384 ]] #0 !orig=[1383],1028,[840] !jvms: Tests::test @ bci:3 IeeeRecommendedTests::testFloatBooleanMethods @ bci:251 2137 IfTrue === 2135 [[ 1653 ]] #1 !orig=[1373],1013,[841],851 !jvms: Tests::test @ bci:3 IeeeRecommendedTests::testFloatBooleanMethods @ bci:251 1248 IfTrue === 1247 [[ 1845 ]] #1 !orig=1159,[1078],1013,[841],851 !jvms: Tests::test @ bci:3 IeeeRecommendedTests::testFloatBooleanMethods @ bci:251 1253 IfFalse === 1247 [[ 1254 ]] #0 !orig=1158,[1089],1028,[840] !jvms: Tests::test @ bci:3 IeeeRecommendedTests::testFloatBooleanMethods @ bci:251 1391 Phi === 1384 2141 1443 [[ 1343 ]] #bool 1262 Phi === 1254 1491 1304 [[ 1223 ]] #bool 61 ConL === 0 [[ 283 65 1312 1828 1358 1199 1643 ]] #long:16 57 CheckCastPP === 54 52 [[ 601 1829 844 1930 1829 1828 283 1822 418 284 284 361 482 687 687 996 1643 1637 1061 1930 1199 1200 1200 1644 1810 1816 1278 1733 1644 1312 1313 1313 1358 1358 1597 1411 1733 1591 ]] #float[int:20]:NotNull:exact * !orig=[1236],[1062],[997],[688],[726] !jvms: IeeeRecommendedTests::testFloatBooleanMethods @ bci:4 418 CallStaticJava === 357 257 416 8 1 ( 285 21 57 1191 1 21 369 285 285 ) [[ 419 420 421 423 ]] # Static java.lang.Math::abs float ( float ) Float::isFinite @ bci:1 IeeeRecommendedTests::testFloatBooleanMethods @ bci:162 !jvms: Float::isFinite @ bci:1 IeeeRecommendedTests::testFloatBooleanMethods @ bci:162 53 Initialize === 45 1 56 1 1 52 64 71 78 86 94 102 110 118 126 134 142 158 166 174 182 189 197 205 213 [[ 54 55 ]] !jvms: IeeeRecommendedTests::testFloatBooleanMethods @ bci:4 1358 AddP === _ 57 57 61 [[ 1357 ]] !orig=996,687,[725] !jvms: IeeeRecommendedTests::testFloatBooleanMethods @ bci:228 421 Proj === 418 [[ 870 601 526 844 1060 452 453 1827 482 259 260 258 670 689 995 1198 1821 1277 1311 1357 1410 1590 1596 1636 1642 1809 1815 ]] #2 Memory: @BotPTR *+bot, idx=Bot; !orig=[617],[646] !jvms: Float::isFinite @ bci:1 IeeeRecommendedTests::testFloatBooleanMethods @ bci:162 54 Proj === 53 [[ 923 57 1642 689 285 1815 995 1636 1060 1590 1198 1821 1410 1809 1277 1827 1311 1500 1357 1596 ]] #0 !orig=[959] !jvms: IeeeRecommendedTests::testFloatBooleanMethods @ bci:4 1357 LoadF === 54 421 1358 [[ 1356 1356 1387 1257 ]] @float[int:>=0]:exact+any *, idx=4; #float !orig=995,689,[727] !jvms: IeeeRecommendedTests::testFloatBooleanMethods @ bci:228 1356 CmpF === _ 1357 1357 [[ 1355 1490 ]] !orig=994,780 !jvms: Float::isNaN @ bci:3 Tests::isUnordered @ bci:8 IeeeRecommendedTests::testFloatBooleanMethods @ bci:235
01-02-2016