JDK-8357105 : C2: compilation fails with "assert(false) failed: empty program detected during loop optimization"
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 8,11,17,21,25
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2025-05-16
  • Updated: 2025-07-14
  • Resolved: 2025-05-26
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 11 JDK 17 JDK 21 JDK 25 JDK 8
11.0.29-oracleFixed 17.0.16-oracleFixed 21.0.8-oracleFixed 25 b25Fixed 8u471Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
C2: compilation fails with "assert(false) failed: empty program detected during loop optimization" when compiling a program exhibiting stacked string concatenation optimizations, if the source code is compiled with -XDstringConcat=inline:

<jdk>/bin/javac -XDstringConcat=inline TestStackedConcatsInline.java && <jdk>/bin/java  TestStackedConcatsInline


Current CompileTask:
C2:103   35       4       TestStackedConcatsInline::f (53 bytes)

Stack: [0x00007f6d9462b000,0x00007f6d9472b000],  sp=0x00007f6d94725ca0,  free space=1003k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x14ef546]  PhaseIdealLoop::build_and_optimize()+0xb96  (loopnode.cpp:4652)
V  [libjvm.so+0xb24c63]  PhaseIdealLoop::optimize(PhaseIterGVN&, LoopOptsMode)+0x4f3
V  [libjvm.so+0xb1c096]  Compile::optimize_loops(PhaseIterGVN&, LoopOptsMode)+0xb6
V  [libjvm.so+0xb1eda1]  Compile::Optimize()+0xcc1
V  [libjvm.so+0xb21eeb]  Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x1f0b
V  [libjvm.so+0x951697]  C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x467
V  [libjvm.so+0xb2fb28]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0xb58
V  [libjvm.so+0xb30cf8]  CompileBroker::compiler_thread_loop()+0x578
V  [libjvm.so+0x107bebb]  JavaThread::thread_main_inner()+0x13b
V  [libjvm.so+0x1aab6d6]  Thread::call_run()+0xb6
V  [libjvm.so+0x173a198]  thread_native_entry(Thread*)+0x128

Comments
Fix request [17u,21u] I backport this for parity with 17.0.16-oracle,21.0.8-oracle. Medium risk. C2 changes always are critical, but this one just adds a bail out. This seems to be urgent, so I think we should also take it to the July update. There is still enough test coverage of the July update to be expected. Clean backport. Test passes, but unfortunately does not reproduce the issue. SAP nightly testing passed.
06-06-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk17u/pull/406 Date: 2025-06-05 09:40:33 +0000
05-06-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk21u/pull/463 Date: 2025-06-05 09:40:24 +0000
05-06-2025

Changeset: a300c356 Branch: master Author: Daniel Skantz <dskantz@openjdk.org> Date: 2025-05-26 14:22:12 +0000 URL: https://git.openjdk.org/jdk/commit/a300c356555019a42c19bf0c16184f6dee4ad96e
26-05-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/25395 Date: 2025-05-22 15:19:08 +0000
22-05-2025

Alternatively, just cover the given case Call<unstable if>(IfFalse(If(Bool(CmpP(Proj(Call(...): https://github.com/openjdk/jdk/compare/master...danielogh:jdk:stringopts_3?expand=1
22-05-2025

It appears to me that the two new bugs: JDK-8357105 JDK-8356246 and previous bugs: JDK-8291775 JDK-8271341 all manifest as a result of trying to handle the pattern CmpP(Proj(CallStaticJava(... during stacked string concatenations (trying to merge two stringbuilder-append-tostring() chains into one). Where CmpP is wired in to the second string builder chain in different ways (valueOf, uncommon traps, maybe other uses). I'm not sure if it's worth handling this case at all given that stacked string concatenations are a niche optimization and the CmpP case has resulted in bug tails. EDIT: I could so far only find one method that's optimized on the CmpP case and that is not invalidated by either of the existing validate_control_flow or validate_mem_flow checks, which is the regression test taken from JDK-8291775: Test7179138_1.
19-05-2025

Possible solution: https://github.com/openjdk/jdk/compare/master...danielogh:jdk:stringopts
19-05-2025

First reproduces with jdk-21+16. Narrowing it down ... Update: Ah, it's just because we added the assert with JDK-8303951. It also reproduces before with -XX:+AbortVMOnCompilationFailure This is a really old issue, I can reproduce this already with JDK 8.
16-05-2025

ILW = Assert in loop opts (harmless / bail out in product), reproducible with alternative string concat implementation in javac (-XDstringConcat=inline), -XX:-OptimizeStringConcat = HLM = P3
16-05-2025

Attached [tostring_resultproj_used_by_uncommon_trap]. This is another case of a complex merge point between two string builder chains (SB1 ends at N120 and SB2 starts at 152). The result projection of SB1 is wired into an uncommon trap and N207 CmpP which gets one of its input replaced by top() as the result projection is removed from the graph. The control flow associated with N211 if goes away and ultimately so does the whole graph.
16-05-2025