JDK-8367405 : [lworld] C2 compilation fails with empty program detected during loop optimization
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: repo-valhalla
  • Priority: P4
  • Status: In Progress
  • Resolution: Unresolved
  • Submitted: 2025-09-11
  • Updated: 2025-10-06
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.
Other
repo-valhallaUnresolved
Related Reports
Relates :  
Description
Running the test from JDK-8357105 with '-XX:-TieredCompilation -XX:+StressUnstableIfTraps' in Valhalla still triggers the issue:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/oracle/valhalla/open/src/hotspot/share/opto/loopnode.cpp:4652), pid=447723, tid=447737
#  assert(false) failed: empty program detected during loop optimization
#
# JRE version: Java(TM) SE Runtime Environment (26.0) (fastdebug build 26-lworldea2-2025-09-10-1323163.tobias...)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 26-lworldea2-2025-09-10-1323163.tobias..., mixed mode, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0x15a7416]  PhaseIdealLoop::build_and_optimize()+0xba6

Current CompileTask:
C2:287   27    b        compiler.stringopts.TestStackedConcatsAppendUncommonTrap::f (53 bytes)

Stack: [0x00007b9e59500000,0x00007b9e59600000],  sp=0x00007b9e595facd0,  free space=1003k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x15a7416]  PhaseIdealLoop::build_and_optimize()+0xba6  (loopnode.cpp:4652)
V  [libjvm.so+0xb81890]  PhaseIdealLoop::optimize(PhaseIterGVN&, LoopOptsMode)+0x4c0  (loopnode.hpp:1173)
V  [libjvm.so+0xb787a4]  Compile::optimize_loops(PhaseIterGVN&, LoopOptsMode)+0xb4  (compile.cpp:2734)
V  [libjvm.so+0xb7bf3c]  Compile::Optimize()+0x16ac  (compile.cpp:3010)
V  [libjvm.so+0xb7e79f]  Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x201f  (compile.cpp:882)
V  [libjvm.so+0x989f34]  C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x484  (c2compiler.cpp:143)
V  [libjvm.so+0xb8dcf8]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0xb58  (compileBroker.cpp:2323)
V  [libjvm.so+0xb8eeb8]  CompileBroker::compiler_thread_loop()+0x568  (compileBroker.cpp:1967)
V  [libjvm.so+0x110e58b]  JavaThread::thread_main_inner()+0x13b  (javaThread.cpp:773)
V  [libjvm.so+0x1bb65a6]  Thread::call_run()+0xb6  (thread.cpp:243)
V  [libjvm.so+0x17fdad8]  thread_native_entry(Thread*)+0x128  (os_linux.cpp:868)

Comments
It could be considered a maybe-not-so-slight variation of JDK-8357105 that is not "caught" early in validate_control_flow. On the other hand it seems that we could actually be "missing" the additional "CheckCastPP" between the Proj and Phi at the end of the validation anyway. In mainline, when processing the uses of the Proj node, Phi is making the validation fail. In Valhalla the validation loop skips "CheckCastPP" here https://github.com/openjdk/valhalla/blob/708b4f92431df90c115dac840fb8194ec3aac3fe/src/hotspot/share/opto/stringopts.cpp#L1138-L1145 (which I guess it could be rightly considered as "transparent" from a coalescing point of view) but then adds its uses (the Phi node) to the worklist. So, the Phi node is never processed as output of another node (where the selection is made).
06-10-2025

(The other solution is to try to support some extended patterns, as suggested by Dean in the PR for JDK-8362117, by retaining information from the first SB. Not sure if there is an easy way to do this.) Not sure. I am only aware of two patterns that we are successfully optimizing, 1) simple use of the toString result of SB1 once: in the constructor of SB2; 2) toString result of SB1 is used in both the constructor and as an argument (direct input to an append) in SB2. The second pattern has broken multiple times, and spot fixes (?) were made in JDK-7179138, JDK-8271341, JDK-8291775. I get the impression only case 1) was considered when writing JDK-6892658, but that's difficult to tell for sure.
06-10-2025

[~dskantz] this sounds promising, do you have any good idea to turn stacked optimization's pattern matching into an "allowlist" approach, as opposed to today's "denylist" approach (which indeed seems dangerous, as it seems impossible to guarantee that we cover exhaustively all cases that can go wrong)?
06-10-2025

Looks like a slight variation of JDK-8357105 but the pattern added there does not cover this because of the intermediate CheckCastPP. The list of related bugs is growing quite large (I think starting with JDK-7179138?). Maybe stacked concatenation needs to be constrained to known safe uses of the result projection of the first concatenation when coalescing.
30-09-2025

Damon, please have a look and sync with [~dskantz] who is familiar with the String Concat code. Thanks!
11-09-2025

Problem listed with https://github.com/openjdk/valhalla/pull/1571.
11-09-2025

I had a look at this and the following Valhalla specific code seem to confuse the String Concat optimzation in C2 so that it does *not* bail out in Valhalla (although it should): https://github.com/openjdk/valhalla/blob/a7b140495f6a5f289f609188aab5f8bee009adef/src/hotspot/share/opto/parse2.cpp#L2098-L2101 It adds an additional CheckCastPP node in the graph that carries the speculative type information. In mainline, we bail out here (output is from -XX:+PrintOptimizeStringConcat): https://github.com/openjdk/valhalla/blob/a7b140495f6a5f289f609188aab5f8bee009adef/src/hotspot/share/opto/stringopts.cpp#L1147-L1153 [...] considering stacked concats extra uses for result: 148 Proj === 120 [[ 221 207 152 189 172 189 289 ]] #5 Oop:java/lang/String (java/io/Serializable,java/lang/Comparable,java/lang/CharSequence,java/lang/constant/Constable,java/lang/constant/ConstantDesc):exact * !jvms: TestStackedConcatsAppendUncommonTrap::f @ bci:18 (line 51) 221 Phi === 219 220 148 [[ 222 230 289 290 ]] #java/lang/String (java/io/Serializable,java/lang/Comparable,java/lang/CharSequence,java/lang/constant/Constable,java/lang/constant/ConstantDesc):exact * Oop:java/lang/String (java/io/Serializable,java/lang/Comparable,java/lang/CharSequence,java/lang/constant/Constable,java/lang/constant/ConstantDesc):exact * !jvms: TestStackedConcatsAppendUncommonTrap::f @ bci:44 (line 52) stacking would fail But in Valhalla we don't bail out. For details see "207 CheckCastPP" in attached ProblematicCheckCastPP.png and also in the diff graph ProblematicCheckCastPP.png.
11-09-2025