JDK-8367483 : C2 crash in PhaseValues::type: assert(t != nullptr) failed: must set before get - missing notification for CastX2P(SubL(x, y))
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 26
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2025-09-12
  • Updated: 2025-09-12
  • Resolved: 2025-09-12
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 26
26 masterFixed
Related Reports
Relates :  
Relates :  
Description
Tests:
 -compiler/loopopts/superword/TestAliasingFuzzer.java#random-flags
- compiler/loopopts/superword/TestAliasingFuzzer.java#vanilla

----------------------------------------------------------------------------------------------------------------------------------------------

Happens during -XX:VerifyIterativeGVN=1110, so it is caught by the verification from JDK-8347273.

I just integrated adding the flag to stress testing, so now it triggers intermittently: JDK-8367301

The failing test is a fuzzing style test (generates random code, failure thus intermittent) from JDK-8324751.

[~chagedorn] said it already failed when the flag was introduced, i.e. with JDK-8347273.

----------------------------------------------------------------------------------------------------------------------------------------------

Root cause:
- CastX2PNode::Ideal optimizes cases:
  - CastX2P(AddX(x, y)) -> AddP(CastX2P(x), y)
  - CastX2P(SubL(x, y)) -> AddP(CastX2P(x), SubL(0, y))
- But the notification code PhaseIterGVN::add_users_of_use_to_worklist only adds CastX2P to the worklist for the AddX and not the SubX cases.


diff --git a/src/hotspot/share/opto/phaseX.cpp b/src/hotspot/share/opto/phaseX.cpp
index 00b36d0bf43..d595946f9b3 100644
--- a/src/hotspot/share/opto/phaseX.cpp
+++ b/src/hotspot/share/opto/phaseX.cpp
@@ -2645,7 +2645,7 @@ void PhaseIterGVN::add_users_of_use_to_worklist(Node* n, Node* use, Unique_Node_
       worklist.push(cmp);
     }
   }
-  if (use->Opcode() == Op_AddX) {
+  if (use->Opcode() == Op_AddX || use->Opcode() == Op_SubX) {
     for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) {
       Node* u = use->fast_out(i2);
       if (u->Opcode() == Op_CastX2P) {

----------------------------------------------------------------------------------------------------------------------------------------------

The root cause is a missing optimization for CastX2P.

Missed Ideal optimization (can_reshape=false):
The node was replaced by Ideal.
Old node:
dist dump
---------------------------------------------
   1  4121  SubL  === _ 2933 4132  [[ 4120 ]]  !orig=[4073],[2417],[2321],[2317],[2051],[1754],[1284] !jvms: AbstractMemorySegmentImpl::checkBounds @ bci:16 (line 403) AbstractMemorySegmentImpl::checkAccess @ bci:9 (line 357) AbstractMemorySegmentImpl::checkEnclosingLayout @ bci:10 (line 362) SegmentVarHandle::checkSegment @ bci:18 (line 92) VarHandleSegmentAsFloats::set @ bci:11 (line 75) VarHandleSegmentAsFloats::set @ bci:12 (line 69) VarHandleGuards::guard_LJF_V @ bci:51 (line 642) AbstractMemorySegmentImpl::set @ bci:10 (line 760) AliasingFuzzer::test_343 @ bci:94 (line 1305)
   0  4120  CastX2P  === _ 4121  [[ 4115 ]]  !orig=[2416],[2323]
The result after Ideal:
dist dump
---------------------------------------------
   1  5710  SubL  === _ 122 4132  [[ 5712 ]] 
   1  2932  CastX2P  === _ 2933  [[ 2906 5332 5479 5712 ]]  !orig=[2416],[2323]
   1     1  Con  === 0  [[ ]]  #top
   0  5712  AddP  === _ 1 2932 5710  [[ ]]

----------------------------------------------------------------------------------------------------------------------------------------------

Seen on linux x64 and aarch64. Also reproduced on x64.

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/opt/mach5/mesos/work_dir/slaves/7b1a61fd-59de-400e-939e-76c8ba818320-S93168/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/72222c45-2427-40f5-a620-f7fd6294d46e/runs/39e52483-c0d1-489b-8be4-3d615bbaf7dd/workspace/open/src/hotspot/share/opto/phaseX.hpp:285), pid=2095030, tid=2095064
#  assert(t != nullptr) failed: must set before get
#
# JRE version: Java(TM) SE Runtime Environment (26.0+16) (fastdebug build 26-ea+16-1559)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 26-ea+16-1559, mixed mode, sharing, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0x18527b8]  PhaseValues::type(Node const*) const [clone .isra.0]+0x68
#
# Core dump will be written. Default location: Core dumps may be processed with "/opt/core.sh %p" (or dumping to /opt/mach5/mesos/work_dir/slaves/f7f8bd65-a387-4a2b-b519-702f2fefaf87-S165965/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/4ea1a978-e50c-4f3e-b3c8-0cf1f69fd8eb/runs/bd04db27-db11-497b-8e02-a929c3571c1f/testoutput/test-support/jtreg_open_test_hotspot_jtreg_tier1_compiler_3/scratch/5/core.2095030)
#
# If you would like to submit a bug report, please visit:
#   https://bugreport.java.com/bugreport/crash.jsp
#

---------------  S U M M A R Y ------------

Command Line: -Djava.library.path=/opt/mach5/mesos/work_dir/jib-master/install/jdk-26+16-1559/linux-x64-debug.test/hotspot/jtreg/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:MaxRAMPercentage=4.16667 -Dtest.boot.jdk=/opt/mach5/mesos/work_dir/jib-master/install/jdk/24/36/bundles/linux-x64/jdk-24_linux-x64_bin.tar.gz/jdk-24 -Djava.io.tmpdir=/opt/mach5/mesos/work_dir/slaves/f7f8bd65-a387-4a2b-b519-702f2fefaf87-S165965/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/4ea1a978-e50c-4f3e-b3c8-0cf1f69fd8eb/runs/bd04db27-db11-497b-8e02-a929c3571c1f/testoutput/test-support/jtreg_open_test_hotspot_jtreg_tier1_compiler_3/tmp -XX:-TieredCompilation -XX:VerifyIterativeGVN=1110 -Dir.framework.server.port=44741 -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation -XX:CompilerDirectivesFile=test-vm-compile-commands-pid-2094980.log -XX:CompilerDirectivesLimit=101 -XX:-OmitStackTraceInFastThrow -DShouldDoIRVerification=true -XX:-BackgroundCompilation -XX:CompileCommand=quiet compiler.lib.ir_framework.test.TestVM compiler.loopopts.superword.templated.AliasingFuzzer

Host: AMD EPYC 7J13 64-Core Processor, 12 cores, 23G, Oracle Linux Server release 8.10
Time: Fri Sep 12 04:43:58 2025 UTC elapsed time: 20.015113 seconds (0d 0h 0m 20s)

---------------  T H R E A D  ---------------

Current thread (0x00007fe2981b37e0):  JavaThread "C2 CompilerThread0" daemon [_thread_in_native, id=2095064, stack(0x00007fe27b475000,0x00007fe27b575000) (1024K)]


Current CompileTask:
C2:20015  672    b        compiler.loopopts.superword.templated.AliasingFuzzer::test_683 (116 bytes)

Stack: [0x00007fe27b475000,0x00007fe27b575000],  sp=0x00007fe27b56fc10,  free space=1003k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x18527b8]  PhaseValues::type(Node const*) const [clone .isra.0]+0x68  (phaseX.hpp:285)
V  [libjvm.so+0x1863ca0]  PhaseIterGVN::verify_Value_for(Node*)+0x30  (phaseX.cpp:1138)
V  [libjvm.so+0x1865c07]  PhaseIterGVN::verify_optimize()+0x7e7  (phaseX.cpp:1087)
V  [libjvm.so+0x18669a8]  PhaseIterGVN::optimize()+0x418  (phaseX.cpp:1069)
V  [libjvm.so+0xb8b952]  PhaseIdealLoop::optimize(PhaseIterGVN&, LoopOptsMode)+0x722  (loopnode.hpp:1288)
V  [libjvm.so+0xb82906]  Compile::optimize_loops(PhaseIterGVN&, LoopOptsMode)+0xb6  (compile.cpp:2254)
V  [libjvm.so+0xb856c1]  Compile::Optimize()+0xcc1  (compile.cpp:2503)
V  [libjvm.so+0xb887df]  Compile::Compile(ciEnv*, ciMethod*, int, Options, DirectiveSet*)+0x1f8f  (compile.cpp:859)
V  [libjvm.so+0x9ad776]  C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x466  (c2compiler.cpp:147)
V  [libjvm.so+0xb97c98]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0xb48  (compileBroker.cpp:2342)
V  [libjvm.so+0xb98e20]  CompileBroker::compiler_thread_loop()+0x530  (compileBroker.cpp:1986)
V  [libjvm.so+0x10f746b]  JavaThread::thread_main_inner()+0x13b  (javaThread.cpp:775)
V  [libjvm.so+0x1b5e186]  Thread::call_run()+0xb6  (thread.cpp:243)
V  [libjvm.so+0x17d21c8]  thread_native_entry(Thread*)+0x128  (os_linux.cpp:889)
Registers:
RAX=0x00007fe29fc9c000, RBX=0x00007fe2484b57b0, RCX=0x00007fe29eaf816a, RDX=0x00007fe29eaf817e
RSP=0x00007fe27b56fc10, RBP=0x00007fe27b56fc10, RSI=0x000000000000011d, RDI=0x00007fe29e91f688
R8 =0x0000000000000003, R9 =0x0000000000000000, R10=0x0000000000000000, R11=0x0000000000000005
R12=0x00007fe27b570380, R13=0x0000000000000048, R14=0x00007fe27b56fd80, R15=0x00007fe2484b57b0
RIP=0x00007fe29e39e7b8, EFLAGS=0x0000000000010246, CSGSFS=0x002b000000000033, ERR=0x0000000000000006
  TRAPNO=0x000000000000000e

XMM[0]=0xfefefefefefefefe 0xfefefefefefefefe
XMM[1]=0x0000000000000000 0xffffffff80000000
XMM[2]=0x0000000000000000 0x000000007fffffff
XMM[3]=0x0000000000000000 0x000000007fffffff
XMM[4]=0x0000000000000000 0x00000000ffffffff
XMM[5]=0x0000000000000000 0xffffffff80000000
XMM[6]=0x0000000000000000 0x0000000000000000
XMM[7]=0x0000000000000000 0x0000000000000000
XMM[8]=0x3437322031205f20 0x3d3d3d2020506464
XMM[9]=0x0000000000000000 0xbbbd05546abbf59c
XMM[10]=0x0000000000000000 0x3fd5a42ab0f4cfe2
XMM[11]=0x0000000000000000 0x4376345785d8a000
XMM[12]=0xc19bf1749bdc06a7 0x80deb1fe72be5d74
XMM[13]=0x550c7dc3243185be 0x12835b01d807aa98
XMM[14]=0xab1c5ed5923f82a4 0x59f111f13956c25b
XMM[15]=0x0000000000000000 0x0000000000000000
  MXCSR=0x00001fa2

Comments
These two sub-test failures do not happen in every Tier5 run so I've added the intermittent label.
12-09-2025

This fix for this bug is integrated in jdk-26+16-1566.
12-09-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/27249 Date: 2025-09-12 08:18:40 +0000
12-09-2025

ILW = Missing optimization opportunity, only crash in debug, no workaround = MLH = P4 Possibly affects older versions but can only trace it back to JDK-8347273 which introduced verification for Ideal.
12-09-2025

Happens during -XX:VerifyIterativeGVN=1110, so it is caught by the verification from JDK-8347273. I just integrated adding the flag to stress testing, so now it triggers intermittently: JDK-8367301 The failing test is a fuzzing style test (generates random code, failure thus intermittent) from JDK-8324751. The root couse is probably something else though. I'll try to extract a reproducer.
12-09-2025

Ok, I have a nice and small reproducer, Test.java java -Xbatch -XX:CompileCommand=compileonly,Test::test -XX:VerifyIterativeGVN=1110 -XX:-TieredCompilation Test.java
12-09-2025

I was able to reproduce it like this: time /home/empeter/Documents/oracle/jtreg/bin/jtreg -va -s -jdk:/home/empeter/Documents/oracle/jdk-fork2/build/linux-x64-debug/jdk -javaoptions:"-XX:-TieredCompilation -XX:VerifyIterativeGVN=1110 -Djdk.test.lib.random.seed=6075703326121148248" -J-Djavatest.maxOutputSize=10000000 /home/empeter/Documents/oracle/jdk-fork2/open/test/hotspot/jtreg/compiler/loopopts/superword/TestAliasingFuzzer.java#random-flags ---------------------------------------------------------------------------------------------------------------------------------------------- The root cause is really a missing optimization: Missed Ideal optimization (can_reshape=false): The node was replaced by Ideal. Old node: dist dump --------------------------------------------- 1 4121 SubL === _ 2933 4132 [[ 4120 ]] !orig=[4073],[2417],[2321],[2317],[2051],[1754],[1284] !jvms: AbstractMemorySegmentImpl::checkBounds @ bci:16 (line 403) AbstractMemorySegmentImpl::checkAccess @ bci:9 (line 357) AbstractMemorySegmentImpl::checkEnclosingLayout @ bci:10 (line 362) SegmentVarHandle::checkSegment @ bci:18 (line 92) VarHandleSegmentAsFloats::set @ bci:11 (line 75) VarHandleSegmentAsFloats::set @ bci:12 (line 69) VarHandleGuards::guard_LJF_V @ bci:51 (line 642) AbstractMemorySegmentImpl::set @ bci:10 (line 760) AliasingFuzzer::test_343 @ bci:94 (line 1305) 0 4120 CastX2P === _ 4121 [[ 4115 ]] !orig=[2416],[2323] The result after Ideal: dist dump --------------------------------------------- 1 5710 SubL === _ 122 4132 [[ 5712 ]] 1 2932 CastX2P === _ 2933 [[ 2906 5332 5479 5712 ]] !orig=[2416],[2323] 1 1 Con === 0 [[ ]] #top 0 5712 AddP === _ 1 2932 5710 [[ ]] ---------------------------------------------------------------------------------------------------------------------------------------------- HOW TO EXTRACT THE TEST: - hs_err file tells us that this method had the failure: compiler.loopopts.superword.templated.AliasingFuzzer::test_343 - Extract the generated code: - "find -name AliasingFuzzer.java" -> ./JTwork/scratch/compile-framework-sources-7537672200127502004/compiler/loopopts/superword/templated/AliasingFuzzer.java - Now I extract the whole test and create a new JTREG test here: -> test/hotspot/jtreg/compiler/c2/Test_8367483.java -> Of course we need to add the @run for JTREG at the top. -> And we also need to remove the "framework.addFlags("-classpath"..." -> adjust package and class name - Run the new JTREG test, with the same flags, just in case: time /home/empeter/Documents/oracle/jtreg/bin/jtreg -va -s -jdk:/home/empeter/Documents/oracle/jdk-fork2/build/linux-x64-debug/jdk -javaoptions:"-XX:-TieredCompilation -XX:VerifyIterativeGVN=1110 -Djdk.test.lib.random.seed=6075703326121148248" -J-Djavatest.maxOutputSize=10000000 /home/empeter/Documents/oracle/jdk-fork2/open/test/hotspot/jtreg/compiler/c2/Test_8367483.java And baaaaam, I get the same reproduction, same missed optimization and assert: # Internal Error (/home/empeter/Documents/oracle/jdk-fork2/open/src/hotspot/share/opto/phaseX.hpp:285), pid=1501980, tid=1501996 # assert(t != nullptr) failed: must set before get - Now that we have a solit reproducer, we can reduce it, cut out the unnecessary tests etc. But that would not be necessary to file the bug at first, so this is optional. - In my case, removing all other tests worked, so that's nice. - At this point, I'm trying to extract a stand-alone Test.java, and just go at it manually. That takes a bit of practice/expertise.
12-09-2025

Changeset: 02d7281b Branch: master Author: Emanuel Peter <epeter@openjdk.org> Date: 2025-09-12 12:06:18 +0000 URL: https://git.openjdk.org/jdk/commit/02d7281b93296e7700e215804cb9e2f8341cab06
12-09-2025