I would appreciate some credit in the PR, I took quite a while to extract a nice "X.jasm" from a larger set of classfiles, and reducing it to just a few lines of code.
Affected seem to be current (JDK24) - JDK17. JDK11 did not reproduce. [~thartmann] said it is a regression of JDK-8252372.
emanuel@emanuel-oracle:/oracle-work/triage/new$ java -jar ~/Documents/asmtools-7.0-build/release/lib/asmtools.jar jasm X.jasm
emanuel@emanuel-oracle:/oracle-work/triage/new$ /oracle-work/jdk-fork4/build/linux-x64-debug/jdk/bin/java -XX:CompileCommand=printcompilation,X::* -XX:CompileCommand=compileonly,X::test -Xcomp X
CompileCommand: PrintCompilation X.* bool PrintCompilation = true
CompileCommand: compileonly X.test bool compileonly = true
586 26 b 3 X::test (40 bytes)
587 27 b 4 X::test (40 bytes)
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/oracle-work/jdk-fork4/open/src/hotspot/share/opto/loopopts.cpp:1071), pid=2960708, tid=2960722
# assert(!n_loop->is_member(get_loop(lca))) failed: control must not be back in the loop
#
# JRE version: Java(TM) SE Runtime Environment (24.0) (fastdebug build 24-internal-2024-07-23-0635220.emanuel...)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 24-internal-2024-07-23-0635220.emanuel..., compiled mode, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V [libjvm.so+0x12a70b9] PhaseIdealLoop::try_move_store_after_loop(Node*) [clone .part.0]+0x9e9
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E" (or dumping to /oracle-work/triage/new/core.2960708)
#
# An error report file with more information is saved as:
# /oracle-work/triage/new/hs_err_pid2960708.log
#
# Compiler replay data is saved as:
# /oracle-work/triage/new/replay_pid2960708.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Aborted (core dumped)
Current CompileTask:
C2:616 27 b 4 X::test (40 bytes)
Stack: [0x00007fb2c5537000,0x00007fb2c5638000], sp=0x00007fb2c5632cb0, free space=1007k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.so+0x12a70b9] PhaseIdealLoop::try_move_store_after_loop(Node*) [clone .part.0]+0x9e9 (loopopts.cpp:1071)
V [libjvm.so+0x12aadd6] PhaseIdealLoop::split_if_with_blocks(VectorSet&, Node_Stack&)+0x96 (loopopts.cpp:1964)
V [libjvm.so+0x129d429] PhaseIdealLoop::build_and_optimize()+0xee9 (loopnode.cpp:4815)
V [libjvm.so+0x9e90c0] PhaseIdealLoop::optimize(PhaseIterGVN&, LoopOptsMode)+0x390 (loopnode.hpp:1117)
V [libjvm.so+0x9e1da5] Compile::optimize_loops(PhaseIterGVN&, LoopOptsMode)+0x75 (compile.cpp:2171)
V [libjvm.so+0x9e4531] Compile::Optimize()+0xe21 (compile.cpp:2418)
V [libjvm.so+0x9e7c76] Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x1b06 (compile.cpp:852)
V [libjvm.so+0x835885] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x1d5 (c2compiler.cpp:142)
V [libjvm.so+0x9f38b8] CompileBroker::invoke_compiler_on_method(CompileTask*)+0x928 (compileBroker.cpp:2303)
V [libjvm.so+0x9f4548] CompileBroker::compiler_thread_loop()+0x478 (compileBroker.cpp:1961)
V [libjvm.so+0xe9cffc] JavaThread::thread_main_inner()+0xcc (javaThread.cpp:757)
V [libjvm.so+0x17bd736] Thread::call_run()+0xb6 (thread.cpp:225)
V [libjvm.so+0x14a55b7] thread_native_entry(Thread*)+0x127 (os_linux.cpp:858)
A quick investigation with RR:
(rr) p n->dump_bfs(10,0,"c#")
dist dump
---------------------------------------------
10 67 ParsePredicate === 66 20 [[ 68 76 ]] #Profiled_Loop #useless !jvms: X::test @ bci:0
9 76 IfTrue === 67 [[ 77 ]] #1 !jvms: X::test @ bci:0
8 77 ParsePredicate === 76 20 [[ 78 86 ]] #Loop_Limit_Check #useless !jvms: X::test @ bci:0
7 314 IfFalse === 351 [[ 244 ]] #0 !orig=[144] !jvms: X::test @ bci:5
7 86 IfTrue === 77 [[ 244 ]] #1 !jvms: X::test @ bci:0
6 370 IfFalse === 349 [[ 355 356 ]] #0 !orig=[350],314,[144] !jvms: X::test @ bci:5
6 244 Loop === 244 86 314 [[ 244 239 240 287 376 ]] !orig=[87] !jvms: X::test @ bci:0
5 355 SafePoint === 370 1 290 1 1 356 1 346 1 [[ 351 ]] SafePoint !orig=310,220 !jvms: X::test @ bci:37
5 376 NeverBranch === 244 [[ 377 378 ]]
4 351 OuterStripMinedLoopEnd === 355 92 [[ 352 314 ]] P=0.900000, C=-1.000000
4 377 CProj === 376 [[ 298 ]] #0
3 349 CountedLoopEnd === 363 348 [[ 370 143 ]] [lt] P=0.900000, C=-1.000000 !orig=[142] !jvms: X::test @ bci:5
3 352 IfTrue === 351 [[ 353 ]] #1
3 298 SafePoint === 377 1 296 1 1 287 1 92 1 92 133 [[ 293 353 ]] SafePoint !orig=134 !jvms: X::test @ bci:5
2 143 IfTrue === 349 [[ 363 ]] #1 !jvms: X::test @ bci:5
2 353 OuterStripMinedLoop === 353 298 352 [[ 353 363 ]]
1 363 CountedLoop === 363 353 143 [[ 360 362 363 364 365 361 349 381 ]] stride: 2 strip mined !orig=[354],[311],[283] !jvms: X::test @ bci:16
0 360 StoreC === 363 364 149 206 [[ 290 239 ]] @java/lang/Class (java/io/Serializable,java/lang/constant/Constable,java/lang/reflect/AnnotatedElement,java/lang/invoke/TypeDescriptor,java/lang/reflect/GenericDeclaration,java/lang/reflect/Type,java/lang/invoke/TypeDescriptor$OfField):exact+120 *, name=c, idx=4; Memory: @java/lang/Class (java/io/Serializable,java/lang/constant/Constable,java/lang/reflect/AnnotatedElement,java/lang/invoke/TypeDescriptor,java/lang/reflect/GenericDeclaration,java/lang/reflect/Type,java/lang/invoke/TypeDescriptor$OfField):exact+120 *, name=c, idx=4; !orig=[295],271,[211] !jvms: X::test @ bci:25
(rr) p lca->dump()
363 CountedLoop === 363 353 143 [[ 360 362 363 364 365 361 349 381 ]] stride: 2 strip mined !orig=[354],[311],[283] !jvms: X::test @ bci:16
$8 = void
(rr) p n_loop->dump()
Loop: N363/N143 counted [0,10),+2 (2147483648 iters) strip_mined
-> looks like another infinite-loop bug.