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: Resolved
  • Resolution: Fixed
  • Submitted: 2025-09-11
  • Updated: 2025-10-20
  • Resolved: 2025-10-20
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-valhallaFixed
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
Not really. Even testing with the ad-hoc Valhalla fix in mainline didn't show any apparent issue. On the other hand trying with more generic solutions (like only adding the current use and handling Phi node to skip string null checks) was fixing the problem with the CheckCastPP node but uncovering other issues elsewhere.
20-10-2025

Good analysis and nice to get a fix in Valhalla. [~dfenacci], did you find any more problems in mainline as well?
20-10-2025

A pull request was submitted for review. Branch: lworld URL: https://git.openjdk.org/valhalla/pull/1675 Date: 2025-10-13 15:38:11 +0000
17-10-2025

The reason Test7179138_1.java string concatenation fails is a Phi after a CastPP that makes the concatenation fail if we add the cast to the worklist. The Phi comes from the null check of String.valueOf which is skipped when merging (by skip_string_null_check) but apparently not when verifying. I'm wondering if only adding the uses of CastPP/CheckCastPP was done on purpose with the assumption that it would (always?) be followed by a Phi coming from a null check. In any case it is definitely not so in Valhalla.
13-10-2025

I wonder if the CheckCastPP was missing all along since JDK-6892658, but in JDK-7179138 the approach chosen was to try to support additional patterns instead of disallowing them.
13-10-2025

Adding "CheckCastPP" itself seemed a sensible thing to do but, as pointed out by [~dskantz], it seems that doing so prevents some string concatenation optimisations to happen, for instance the one in compiler/c2/Test7179138_1.java
13-10-2025

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