JDK-8303466 : C2: failed: malformed control flow. Limit type made precise with MaxL/MinL
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 11,17,19,20,21
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2023-03-01
  • Updated: 2024-11-11
  • Resolved: 2023-04-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 Other
11.0.24Fixed 17.0.12Fixed 21 b20Fixed openjdk8u422Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
Attached Test.java triggers compilation bailout.

https://github.com/openjdk/jdk/blob/8f195ff236000d9c019f8beb2b13355083e211b5/src/hotspot/share/opto/compile.cpp#L3992

I set an assert at that position, and debugged it quickly. The issue seems to be that there is an IfNode with only one Proj output. This is obviously a BUG. Going futher back, it seems the second projection was removed during dead code removal.

Run with
./java -XX:CompileCommand=compileonly,Test::test -XX:MaxVectorSize=64 -Xcomp -XX:CompileCommand=dontinline,Test::* -XX:+UnlockExperimentalVMOptions -XX:PerMethodSpecTrapLimit=0 -XX:PerMethodTrapLimit=0 -XX:+PrintCompilation -XX:CompileCommand=quiet Test.java

In the PrintCompilation log, one can find this:

made not compilable on level 3  Test::run (11 bytes)   excluded by CompileCommand
   4123   84    b  3       Test::test (32 bytes)
   4124   85    b  4       Test::test (32 bytes)
   4163   85    b  4       Test::test (32 bytes)   COMPILE SKIPPED: malformed control flow (retry at different tier)

I found this bug during my work of JDK-8298935. The IR framework complained that one of my test functions is "not compilable (anymore) at level C2".

We should probably add
assert(false, "reason")
to as many bailout locations as possible, so that we can detect bugs in debug mode, rather than just ignoring broken graphs.
Comments
[jdk8u-fix-request] Approval Request from Martin Balao Alonso jdk8u is affected by this bug and would benefit from its fix. The patch does not apply cleanly but has been reviewed.
29-06-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk8u-dev/pull/529 Date: 2024-06-27 21:21:10 +0000
28-06-2024

[jdk11u-fix-request] Approval Request from Martin Balao Alonso jdk11u is affected by this bug and would benefit from its fix. The patch does not apply cleanly but has been reviewed.
26-06-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk11u-dev/pull/2814 Date: 2024-06-25 15:21:50 +0000
25-06-2024

[jdk17u-fix-request] Approval Request from Martin Balao Alonso jdk17u is affected by this bug and would benefit from its fix. The patch does not apply cleanly but has been reviewed.
25-06-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk17u-dev/pull/2635 Date: 2024-06-25 04:46:52 +0000
25-06-2024

This matches more or less the number of sightings with JSR166TestCase.java in our CI. Looks like this is the only (known) test that triggers the assert in this specific way with late inlining.
06-09-2023

Hi [~chagedorn] we see this assertion rather often in our nightly tests; ~ 5-10 times per month. The java/util/concurrent/tck/JSR166TestCase.java test seems to be good at triggering this assert. But correct it is intermittent.
06-09-2023

Hi [~mbaesken], I think this is JDK-8312980 where incremental inlining is causing the graph to become malformed. It is highly intermittent due to requiring a specific profile in order to inline some methods late to trigger the assert.
06-09-2023

today we saw another assert this time on linuxx86_64 (fastdebug); triggered by test java/util/concurrent/tck/JSR166TestCase.java # Internal Error (/openjdk/linuxx86_64/jdk/src/hotspot/share/opto/compile.cpp:4013), pid=1735295, tid=1770794 # assert(false) failed: malformed control flow Current CompileTask: C2: 75855 6145 4 java.util.stream.ForEachOps$ForEachTask::compute (183 bytes) Stack: [0x00007f91a98fa000,0x00007f91a99fa000], sp=0x00007f91a99f5290, free space=1004k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [libjvm.so+0xa163a1] Compile::final_graph_reshaping()+0x11f1 (compile.cpp:4013) V [libjvm.so+0xa177be] Compile::Optimize()+0x136e (compile.cpp:2466) V [libjvm.so+0xa19530] Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x1b70 (compile.cpp:854) V [libjvm.so+0x86f71b] C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x13b (c2compiler.cpp:119) V [libjvm.so+0xa25bb0] CompileBroker::invoke_compiler_on_method(CompileTask*)+0xb10 (compileBroker.cpp:2283) V [libjvm.so+0xa26a68] CompileBroker::compiler_thread_loop()+0x618 (compileBroker.cpp:1944) V [libjvm.so+0xeef15e] JavaThread::thread_main_inner()+0xee (javaThread.cpp:720) V [libjvm.so+0x18fae8a] Thread::call_run()+0xba (thread.cpp:220) V [libjvm.so+0x14e2fda] thread_native_entry(Thread*)+0x12a (os_linux.cpp:785) Registers: RAX=0x00007f9223b10000, RBX=0x00007f922360a7a4, RCX=0x00007f9222fbec18, RDX=0x00007f9222fa8022 RSP=0x00007f91a99f5290, RBP=0x00007f91a99f5490, RSI=0x0000000000000fad, RDI=0x00007f9223062808 R8 =0x0000000000000000, R9 =0x0000000000000000, R10=0x0000000000000001, R11=0x0000000000000293 R12=0x00007f91a99f78d0, R13=0x0000000000000002, R14=0x00007f9180633b98, R15=0x00007f91a99f52f0 RIP=0x00007f9221e163a1, EFLAGS=0x0000000000010246, CSGSFS=0x002b000000000033, ERR=0x0000000000000006 TRAPNO=0x000000000000000e Should I maybe open a new JBS issue for this ?
06-09-2023

[~dcubed] Good to hear it reduced the frequency. The "malformed control flow" has so far triggered 3 bugs: JDK-8303466 (this here), JDK-8306997, JDK-8288981.
02-05-2023

[~epeter] > But the assert will still trigger with the fuzzer occasionally. > > The assert will now still fail with the fuzzer occasionally because of the `assertion / skeleton > predicate` bug that [~chagedorn] is already working on for a while. But I hope this fix will > drastically reduce the rate of fuzzer failures with this assert. Definitely an improvement on frequency. Here's the bug that I filed for the first sighting since your fix went in: JDK-8307131 C2: assert(false) failed: malformed control flow
28-04-2023

This fix is integrated in jdk-21+20-1660.
28-04-2023

Changeset: cc894d84 Author: Emanuel Peter <epeter@openjdk.org> Date: 2023-04-26 05:42:26 +0000 URL: https://git.openjdk.org/jdk/commit/cc894d849aa5f730d5a806acfc7a237cf5170af1
26-04-2023

I now integrated the fix. But the assert will still trigger with the fuzzer occasionally. The assert will now still fail with the fuzzer occasionally because of the `assertion / skeleton predicate` bug that [~chagedorn] is already working on for a while. But I hope this fix will drastically reduce the rate of fuzzer failures with this assert.
26-04-2023

java/util/concurrent/tck/JSR166TestCase.java jtreg test (in curent jdk head) triggered a similar looking issue on Windows 64bit, see below : # # A fatal error has been detected by the Java Runtime Environment: # # Internal Error (d:\openjdk\jdk-dev\src\hotspot\share\opto\compile.cpp:4003), pid=59848, tid=77048 # assert(false) failed: malformed control flow # # JRE version: OpenJDK Runtime Environment (21.0) (fastdebug build 21-internal-adhoc.jdk-dev) # Java VM: OpenJDK 64-Bit Server VM (fastdebug 21-internal-adhoc.jdk-dev, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64) . . . --------------- T H R E A D --------------- Current thread (0x000001a367335650): JavaThread "C2 CompilerThread0" daemon [_thread_in_native, id=77048, stack(0x0000009d2ed00000,0x0000009d2ee00000)] Current CompileTask: C2: 47387 6171 4 java.util.stream.ForEachOps$ForEachTask::compute (183 bytes) Stack: [0x0000009d2ed00000,0x0000009d2ee00000] Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) V [jvm.dll+0xbdd4f1] os::win32::platform_print_native_stack+0xf1 (os_windows_x86.cpp:236) V [jvm.dll+0xeee2ec] VMError::report+0x100c (vmError.cpp:815) V [jvm.dll+0xeeff35] VMError::report_and_die+0x645 (vmError.cpp:1588) V [jvm.dll+0xef0644] VMError::report_and_die+0x64 (vmError.cpp:1353) V [jvm.dll+0x53545b] report_vm_error+0x5b (debug.cpp:191) V [jvm.dll+0x4cdb71] Compile::final_graph_reshaping+0xcf1 (compile.cpp:4003) V [jvm.dll+0x4c8ad8] Compile::Optimize+0x1328 (compile.cpp:2450) V [jvm.dll+0x4c5828] Compile::Compile+0x1458 (compile.cpp:841) V [jvm.dll+0x3e474a] C2Compiler::compile_method+0x11a (c2compiler.cpp:121) V [jvm.dll+0x4e0733] CompileBroker::invoke_compiler_on_method+0x883 (compileBroker.cpp:2268) V [jvm.dll+0x4ddeaf] CompileBroker::compiler_thread_loop+0x36f (compileBroker.cpp:1945) V [jvm.dll+0x7b12b4] JavaThread::thread_main_inner+0x224 (javaThread.cpp:718) V [jvm.dll+0xe66496] Thread::call_run+0x1c6 (thread.cpp:229) V [jvm.dll+0xbdbe10] os::win32::thread_native_entry+0xa0 (os_windows.cpp:551) C [ucrtbase.dll+0x2268a] C [KERNEL32.DLL+0x17ab4] C [ntdll.dll+0x5a351]
19-04-2023

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/13269 Date: 2023-03-31 12:44:17 +0000
05-04-2023

I now have a fix for some of these failures. However: some of the asserts seem to be related to missing skeleton/assertion predicates JDK-8288981. Let's see how noisy this assert is after this change is integrated.
05-04-2023

Update: I suspect this is multiple bugs. I am probably close to fixing one of them. But until we fixed everything it may take a bit.
31-03-2023

Draft PR: https://github.com/openjdk/jdk/pull/13269
31-03-2023

Raising priority because this now triggers an assert.
28-03-2023

I've attached a reduced Java Fuzzer case which triggers with AVX 512: $ java -XX:UseAVX=3 -Xcomp -XX:CompileOnly=Test Test5.java
27-03-2023

Thanks [~chagedorn] for reducing it. I cleaned it up by hand (removed infinite loop, etc), and now it is quite simple. ./java -Xcomp -XX:CompileOnly=Test4 -XX:CompileCommand=printcompilation,Test4::* -XX:+TraceLoopOpts Test4.java
24-03-2023

I found a fuzzer test already. Let's see if we can reduce it. ./javac FuzzerUtils.java ./javac Test3.java ./java -Xcomp -XX:CompileOnly=Test3 Test3.java
24-03-2023

Update: since JDK-8303951, this now triggers an assert: dist dump --------------------------------------------- 0 2250 If === 198 2249 [[ 267 ]] P=0.500000, C=-1.000000 1 267 IfFalse === 2250 [[ 316 ]] #0 # # A fatal error has been detected by the Java Runtime Environment: # # Internal Error (/home/emanuel/Documents/fork3-jdk/open/src/hotspot/share/opto/compile.cpp:4003), pid=439330, tid=439343 # assert(false) failed: malformed control flow
23-03-2023

Yes, that makes sense. I see a CastII node that eventually becomes TOP, because of an impossible range (input_type and _type have no overlap). That CastII was Ideal-ed and cloned many times, but its origin is in the new CastII added in JDK-8286625. Maybe we are preserving the type on one path more than another, and that leads to things collapsing Yes, it looks like the zero-trip-count of post-loop does not collapse, but the values going into post-loop do collapse. Need more investigation.
13-03-2023

Build search says that this was introduced/triggered by JDK-8286625 in JDK 19. But that fix was also backported to JDK 17.0.5, where the issue does not reproduce.
02-03-2023

This requires AVX-512, I could reproduce on a non-AVX-512 machine with Intel's SDE.
02-03-2023

I'll try to make this a WhiteBox test, so that we can run build-search and find the breaking change. Update: I created a WhiteBox test that checks for compilation. Test2.java ~/Documents/jtreg/bin/jtreg -va -s -jdk:/home/emanuel/Documents/fork6-jdk/build/linux-x64-debug/jdk/ -javaoptions:"" -J-Djavatest.maxOutputSize=1000000 /home/emanuel/Documents/fork6-jdk/open/test/hotspot/jtreg/compiler/loopopts/superword/Test2.java
01-03-2023

ILW = Bailout from C2 compilation (harmless but affects performance), with single test on AVX-512, -XX:-UseSuperWord or limit MaxVectorSize = MLM = P4
01-03-2023

Both my local laptop and the windows-x64 machine on our testing system have avx512
01-03-2023