JDK-8338100 : C2: assert(!n_loop->is_member(get_loop(lca))) failed: control must not be back in the loop
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 17,21,22,23,24
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2024-08-09
  • Updated: 2024-11-19
  • Resolved: 2024-09-05
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 24
24 b15Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description
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.
Comments
Changeset: e203df46 Branch: master Author: Roland Westrelin <roland@openjdk.org> Date: 2024-09-05 15:51:27 +0000 URL: https://git.openjdk.org/jdk/commit/e203df46faf610e35e2c2510271ad68199f4fa3f
05-09-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/20797 Date: 2024-08-30 15:58:30 +0000
30-08-2024

Roland, could you have a look at this? Thanks.
09-08-2024

ILW = Assert during C2 compilation when trying to sink a store out of a loop, edge case (jasm) but reproducible, disable split if or compilation of affected method = HLM = P3
09-08-2024