JDK-8260370 : C2: LoopLimit node is not eliminated
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 16,17
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2021-01-25
  • Updated: 2023-07-25
  • Resolved: 2021-01-27
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 16 JDK 17
16 b34Fixed 17Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
The attached fuzzer test fails with the following assertion after JDK-8255120:

To reproduce (both will trigger):
# java -Xcomp -XX:CompileOnly=Test Test.java
# java -Xcomp -XX:-TieredCompilation -XX:CompileOnly=Test Test.java

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/opt/mach5/mesos/work_dir/slaves/983c483a-6907-44e0-ad29-98c7183575e2-S154441/frameworks/1735e8a2-a1db-478c-8104-60c8b0af87dd-0196/executors/7ef6f28b-eda9-48e8-bb7a-ac0cee72e955/runs/a9818b83-6452-4ea7-b69c-e87d57f606ab/workspace/open/src/hotspot/share/opto/matcher.cpp:1669), pid=21371, tid=21384
#  assert(false) failed: bad AD file
#
# JRE version: Java(TM) SE Runtime Environment (16.0+33) (fastdebug build 16-ea+33-2205)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 16-ea+33-2205, compiled mode, sharing, tiered, compressed oops, g1 gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0x142407a]  Matcher::Label_Root(Node const*, State*, Node*, Node*&)+0x50a
............
Command Line: -Xmx1G -Xcomp -Xbatch -XX:CompileOnly=Test -XX:CompileCommand=quiet Test
............
Current thread (0x00007f0c484948b0):  JavaThread "C2 CompilerThread0" daemon [_thread_in_native, id=21384, stack(0x00007f0c207fc000,0x00007f0c208fd000)]


Current CompileTask:
C2:   1168   67    b  4       Test::mainTest (758 bytes)

Stack: [0x00007f0c207fc000,0x00007f0c208fd000],  sp=0x00007f0c208f8070,  free space=1008k
Native frames: (J=compiled Java code, A=aot compiled Java code, j=interpreted, Vv=VM code, C=native code)
V  [libjvm.so+0x142407a]  Matcher::Label_Root(Node const*, State*, Node*, Node*&)+0x50a
V  [libjvm.so+0x1424a0c]  Matcher::match_tree(Node const*)+0x20c
V  [libjvm.so+0x1432046]  Matcher::xform(Node*, int)+0xe46
V  [libjvm.so+0x1439bc6]  Matcher::match()+0x4706
V  [libjvm.so+0xa0e81c]  Compile::Code_Gen()+0x9c
V  [libjvm.so+0xa19a57]  Compile::Compile(ciEnv*, ciMethod*, int, bool, bool, bool, bool, DirectiveSet*)+0x1917
V  [libjvm.so+0x849b8c]  C2Compiler::compile_method(ciEnv*, ciMethod*, int, bool, DirectiveSet*)+0x1dc
V  [libjvm.so+0xa297c8]  CompileBroker::invoke_compiler_on_method(CompileTask*)+0xe88
V  [libjvm.so+0xa2a418]  CompileBroker::compiler_thread_loop()+0x5a8
V  [libjvm.so+0x18ba9b6]  JavaThread::thread_main_inner()+0x256
V  [libjvm.so+0x18c1330]  Thread::call_run()+0x100
V  [libjvm.so+0x15a3506]  thread_native_entry(Thread*)+0x116


Output
----------
Default case invoked for: 
   opcode  = 188, "LoopLimit"
o7021  LoopLimit  === _ o7653 o6580  [[o6727 o7036  2092 ]] 

--N: o7021  LoopLimit  === _ o7653 o6580  [[o6727 o7036  2092 ]] 

   --N: o7653  Binary  === _ o6580 o7045  [[o7021 ]] 
   _Binary_rRegI_rRegI  100  _Binary_rRegI_rRegI
   _Binary_rax_RegI_rRegI  100  _Binary_rax_RegI_rRegI

      --N: o6580  ConI  === o0  [[o7021 o7653 o6727 o7198 ]]  #int:-4
      IMMI  10  IMMI
      IMMI8  5  IMMI8
      IMMI16  10  IMMI16
      RREGI  100  loadConI
      RAX_REGI  100  loadConI
      RBX_REGI  100  loadConI
      RCX_REGI  100  loadConI
      RDX_REGI  100  loadConI
      RDI_REGI  100  loadConI
      NO_RAX_RDX_REGI  100  loadConI
      STACKSLOTI  200  storeSSI

      --N: o7045  SubI  === _ o7041 o6378  [[o7653 o7198 ]] 
      RREGI  0  RREGI
      RAX_REGI  0  RAX_REGI
      RBX_REGI  0  RBX_REGI
      RCX_REGI  0  RCX_REGI
      RDX_REGI  0  RDX_REGI
      RDI_REGI  0  RDI_REGI
      NO_RAX_RDX_REGI  0  NO_RAX_RDX_REGI
      STACKSLOTI  100  storeSSI

   --N: o6580  ConI  === o0  [[o7021 o7653 o6727 o7198 ]]  #int:-4
   IMMI  10  IMMI
   IMMI8  5  IMMI8
   IMMI16  10  IMMI16
   RREGI  100  loadConI
   RAX_REGI  100  loadConI
   RBX_REGI  100  loadConI
   RCX_REGI  100  loadConI
   RDX_REGI  100  loadConI
   RDI_REGI  100  loadConI
   NO_RAX_RDX_REGI  100  loadConI
   STACKSLOTI  200  storeSSI


Comments
verified w/ the attached test. JDK-8260608 got filed to check in this test.
28-01-2021

The fix for this bug is integrated in jdk-16+34-2215. The fix for this bug is also integrated in jdk-17+8-465.
28-01-2021

Changeset: e28e1111 Author: Vladimir Ivanov <vlivanov@openjdk.org> Date: 2021-01-27 10:29:59 +0000 URL: https://git.openjdk.java.net/jdk16/commit/e28e1111
27-01-2021

Fix request for JDK 16 approved.
26-01-2021

Fix request (jdk16): The bug is a regression in 16. In product VM it leads to C2 compilation bailouts which can manifest as performance regressions. The fix is low risk and focused on the actual problem. It successfully passed hs-tier1 - hs-tier4 testing and got 1 (R)eview on hotspot-compiler-dev.
26-01-2021

There is duplicated bug JDK-8260324 which I saw first and added comment (moving here): From JDK-5091921: 2. Long arithmetic is used to calculate exact limit only when it is needed: empty loop elimination and predicated range check elimination. New ideal macro node LoopLimitNode is used but corresponding mach node is created only for 32-bit x86 to get better assembler code. Sparc and x64 have long registers so generated assembler is good enough without specialized mach node. Also delay LoopLimitNode transformation until all loop optimizations are done (by marking LoopLimitNode as macro node). LoopLimit should be transformed into Long arithmetic nodes on x64 and should not present after Optimizer: https://github.com/openjdk/jdk/blob/master/src/hotspot/share/opto/loopnode.cpp#L1954 May be when it is put on IGVN list in macro.cpp the major_progress is false: https://github.com/openjdk/jdk/blob/master/src/hotspot/share/opto/loopnode.cpp#L1924
25-01-2021

Attached reduced test by creduce: # java -Xcomp -XX:CompileOnly=Reduced Reduced.java
25-01-2021

ILW = Assert during C2 compilation due to unexpected node in matcher, reproducible with JavaFuzzer test and also showed up in testing with -XX:StressLongCountedLoop, disable compilation of affected method = HMM = P2 Targeting JDK 16 for now. [~vlivanov] please defer if appropriate.
25-01-2021