While testing Leyden Early Release the problem was found in C2 EscapeAnalysis, in new code which handles allocations merge.
In ConnectionGraph::specialize_cmp() the next line is incorrect because it assumes that If node always points to Bool node:
Node* curr_cmp = curr_ctrl->in(0)->in(1)->in(1); // true/false -> if -> bool -> cmp
But loop and predicates optimizations may add Opaque node in between. Which happens in failure case which have next nodes sequence: If -> Opaque4 -> Bool
As result we hit assert in ConnectionGraph::specialize_cmp() when trying to access inputs of Cmp node:
# Internal Error (/work/leyden/open/src/hotspot/share/opto/node.hpp:409), pid=70375, tid=27907
# assert(i < _max) failed: oob: i=2, _max=2
#
# JRE version: Java(TM) SE Runtime Environment (24.0) (fastdebug build 24-internal-2024-06-26-1746082...)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 24-internal-2024-06-26-1746082..., mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, bsd-aarch64)
#
--------------- S U M M A R Y ------------
Command Line: -XX:CacheDataStore=spring-leyden.cds -XX:CDSPreimage=spring-leyden.cds.preimage
Host: mac, "MacBookPro18,3" arm64, 8 cores, 32G, Darwin 23.5.0, macOS 14.5 (23F79)
Time: Thu Jun 27 07:50:52 2024 PDT elapsed time: 9.845733 seconds (0d 0h 0m 9s)
--------------- T H R E A D ---------------
Current thread (0x00000001500ac410): JavaThread "C2 CompilerThread0" daemon [_thread_in_native, id=27907, stack(0x000000016ee00000,0x000000016f003000) (2060K)]
Current CompileTask:
C2: F9845 C0 Q0 S17 3146 b 4 org.springframework.boot.loader.zip.ZipCentralDirectoryFileHeaderRecord::load (156 bytes)
Stack: [0x000000016ee00000,0x000000016f003000], sp=0x000000016effe620, free space=2041k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V [libjvm.dylib+0x11d16b4] VMError::report_and_die(int, char const*, char const*, char*, Thread*, unsigned char*, void*, void*, char const*, int, unsigned long)+0x544 (node.hpp:409)
V [libjvm.dylib+0x11d1e64] VMError::report_and_die(Thread*, unsigned int, unsigned char*, void*, void*)+0x0
V [libjvm.dylib+0x58b25c] print_error_for_unit_test(char const*, char const*, char*)+0x0
V [libjvm.dylib+0x650ba8] ConnectionGraph::specialize_cmp(Node*, Node*)+0x16c
V [libjvm.dylib+0x650c20] ConnectionGraph::specialize_castpp(Node*, Node*, Node*)+0x70
V [libjvm.dylib+0x651d54] ConnectionGraph::reduce_phi_on_castpp_field_load(Node*, GrowableArray<Node*>&, GrowableArray<Node*>&)+0x1b8
V [libjvm.dylib+0x654888] ConnectionGraph::reduce_phi(PhiNode*, GrowableArray<Node*>&, GrowableArray<Node*>&)+0x338
V [libjvm.dylib+0x64baf4] ConnectionGraph::split_unique_types(GrowableArray<Node*>&, GrowableArray<ArrayCopyNode*>&, GrowableArray<MergeMemNode*>&, Unique_Node_List&)+0xabc
V [libjvm.dylib+0x646ea8] ConnectionGraph::compute_escape()+0x1628
V [libjvm.dylib+0x645744] ConnectionGraph::do_analysis(Compile*, PhaseIterGVN*)+0xd8
V [libjvm.dylib+0x4e99e8] Compile::Optimize()+0x4b0
V [libjvm.dylib+0x4e8248] Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x11e0
This code was introduce for ReduceAllocationMerges optimization JDK-8316991 in JDK-23.
There was followup fix JDK-8330853 to add similar checks but it missed
code in specialize_cmp().