RunThese8M/RunThese30M fails with "assert(adr_type != 0LL) failed: expecting TypeKlassPtr" on a fastdebug build of Generational ZGC (see attached HotSpot error files, pid78296 for windows-x64 and pid1054514 for linux-x64). The failure is observed on a Generational ZGC build using -XX:+UseZGC, but it is not GC-specific (can also be reproduced using -XX:+UseParallelGC -XX:-UseCompressedOops).
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (c:\sb\prod\1677586887\workspace\open\src\hotspot\share\opto\memnode.cpp:2289), pid=78296, tid=48652
#  assert(adr_type != 0LL) failed: expecting TypeKlassPtr
Current CompileTask:
C2:1229395 128231 %     4       javasoft.sqe.tests.api.java.util.Collections.ncopies.Stream::lambda$getStreamFactory$2 @ 11 (73 bytes)
Stack: [0x0000002fc8e00000,0x0000002fc8f00000]
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
(...)
V  [jvm.dll+0xbaebeb]  LoadKlassNode::make+0x5b  (memnode.cpp:2289)
V  [jvm.dll+0xdf4b83]  SubTypeCheckNode::load_klass+0x153  (subtypenode.cpp:212)
V  [jvm.dll+0xdf51eb]  SubTypeCheckNode::verify+0x32b  (subtypenode.cpp:183)
V  [jvm.dll+0xdf4973]  SubTypeCheckNode::Ideal+0x2a3  (subtypenode.cpp:113)
V  [jvm.dll+0xcac915]  PhaseIterGVN::transform_old+0xe5  (phaseX.cpp:1356)
V  [jvm.dll+0xca8cb3]  PhaseIterGVN::optimize+0x2b3  (phaseX.cpp:1206)
V  [jvm.dll+0x51c682]  Compile::Optimize+0x1b2  (compile.cpp:2218)
V  [jvm.dll+0x51a43b]  Compile::Compile+0x16bb  (compile.cpp:834)
(...)
FAILURE ANALYSIS
The failure is caused by an implicit assumption made by the verification code within SubTypeCheckNode::Ideal() [1]. This code wrongly assumes that if obj_or_subklass (the ObjOrSubKlass input of the SubTypeCheck node) is a klass or OOP pointer, then 'obj_or_subklass->bottom_type() != TOP'. This assumption does not hold if obj_or_subklass is a projection of the TOP constant node, which can happen within IGVN e.g. if 'obj_or_subklass->in(0)' is an unreachable call node that gets replaced with TOP, as can be seen in before-after-removing-call.png (attached).
The consequence is that 'adr', the node computing the klass address of obj_or_subklass [2], has bottom type TOP, which triggers the reported assertion failure in LoadKlassNode::make() [3]. The failure is not specific to ZGC. It has only been observed with this GC configuration because a specific intermediate Idealization step in the IGVN sequence that leads to the above situation is only performed if UseCompressedOops is disabled. This step replaces a LoadP node with the value stored by a dominating StoreP node that writes into the same address, as can be seen in before-after-load-idealization.png (attached).
This Idealization is not performed if UseCompressedOops is enabled because, unlike LoadP, the corresponding LoadN node is not recorded for IGVN upon creation -- only its successor DecodeN node is [4,5]. This missing optimization opportunity should be addressed separately.
SUGGESTED SOLUTION
To skip verification of SubtypeCheck nodes [1] if 'obj_or_subklass->bottom_type == TOP'. This is a low-risk fix affecting debug-only code. An alternative, more invasive solution, would be to skip the entire SubtypeCheckNode::Ideal() call in this case.
[1] https://github.com/openjdk/jdk/blob/199b1bf5009120efd1fd37a1ddabc0c6fb84f62c/src/hotspot/share/opto/subtypenode.cpp#L113
[2] https://github.com/openjdk/jdk/blob/199b1bf5009120efd1fd37a1ddabc0c6fb84f62c/src/hotspot/share/opto/subtypenode.cpp#L211
[3] https://github.com/openjdk/jdk/blob/199b1bf5009120efd1fd37a1ddabc0c6fb84f62c/src/hotspot/share/opto/memnode.cpp#L2289
[4] https://github.com/openjdk/jdk/blob/bac02b6e9d9e1e93db27c7888188f29631e07f47/src/hotspot/share/opto/graphKit.cpp#L1561-L1566
[5] https://github.com/openjdk/jdk/blob/199b1bf5009120efd1fd37a1ddabc0c6fb84f62c/src/hotspot/share/opto/memnode.cpp#L956