JDK-6675699 : need comprehensive fix for unconstrained ConvI2L with narrowed type
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: hs11,hs20,7,8,8u40,8u60,9
  • Priority: P1
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • Submitted: 2008-03-14
  • Updated: 2023-07-21
  • Resolved: 2016-01-18
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 7 JDK 8 JDK 9 Other
7u241Fixed 8u101Fixed 9 b105Fixed openjdk7uFixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
The problem is that ConvI2L nodes with a narrow type are not dependent on the corresponding range check that proves that the input value is always in the range. As a result, the ConvI2L node may flow above the range check during loop optimizations and end up with an input that is not in its type range (for example, in a peeled iteration of a loop). The node is then replaced by TOP causing the data path to be eliminated. However, because there is no control dependency to the corresponding range check, the path from the peeled iteration that uses the result of the ConvI2L may not be eliminated. We finally crash because we are using a value that is not available (for example, from the old loop body). For details, see TestLoopPeeling.java.

This problem may show up for array accesses but also for other places where we emit a ConvI2L node (for example, array allocation). We solved several instances of this problem in the past with "workaround-fixes" (JDK-6659207, JDK-4781451, JDK-4799512, JDK-6663854) but should implement a robust fix that makes ConvI2L nodes dependent on the range check.

The crash may look similar to this:

Bad graph detected in build_loop_late
n:  181	AddP	=== _  163  182  124  [[ 183 ]]  !jvms: TestLoopPeeling::testArrayAccess @ bci:43
early(n):  200	Loop	===  200  230  192  [[ 200  69  68  84 ]] inner  !orig=[65] !jvms: TestLoopPeeling::testArrayAccess @ bci:8
n->in(1):  163	CastPP	===  156  93  [[ 182  164  164  173  182  181 ]]  #int[int:>=0]:NotNull:exact * !jvms: TestLoopPeeling::testArrayAccess @ bci:43
early(n->in(1)):  156	IfTrue	===  155  [[ 168  163 ]] #1 !jvms: TestLoopPeeling::testArrayAccess @ bci:43
n->in(1)->in(1):  93	DecodeN	=== _  92  [[ 108  95  163 ]]  #int[int:>=0]:exact * !jvms: TestLoopPeeling::testArrayAccess @ bci:20
early(n->in(1)->in(1)):  3	Start	===  3  0  [[ 3  5  6  7  8  9  10  11  12 ]]  #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:TestLoopPeeling:NotNull *, 6:int, 7:int}
n->in(2):  182	AddP	=== _  163  163  128  [[ 181 ]]  !jvms: TestLoopPeeling::testArrayAccess @ bci:43
early(n->in(2)):  200	Loop	===  200  230  192  [[ 200  69  68  84 ]] inner  !orig=[65] !jvms: TestLoopPeeling::testArrayAccess @ bci:8
n->in(2)->in(1):  163	CastPP	===  156  93  [[ 182  164  164  173  182  181 ]]  #int[int:>=0]:NotNull:exact * !jvms: TestLoopPeeling::testArrayAccess @ bci:43
early(n->in(2)->in(1)):  156	IfTrue	===  155  [[ 168  163 ]] #1 !jvms: TestLoopPeeling::testArrayAccess @ bci:43
n->in(2)->in(2):  163	CastPP	===  156  93  [[ 182  164  164  173  182  181 ]]  #int[int:>=0]:NotNull:exact * !jvms: TestLoopPeeling::testArrayAccess @ bci:43
early(n->in(2)->in(2)):  156	IfTrue	===  155  [[ 168  163 ]] #1 !jvms: TestLoopPeeling::testArrayAccess @ bci:43
n->in(2)->in(3):  128	LShiftL	=== _  126  127  [[ 130  182 ]]  !orig=254 !jvms: TestLoopPeeling::testArrayAccess @ bci:24
early(n->in(2)->in(3)):  200	Loop	===  200  230  192  [[ 200  69  68  84 ]] inner  !orig=[65] !jvms: TestLoopPeeling::testArrayAccess @ bci:8
n->in(3):  124	ConL	===  0  [[ 181  129 ]]  #long:16
early(n->in(3)):  0	Root	===  0  50  63  107  123  162  177  198  [[ 0  1  3  23  24  38  45  58  72  81  90  94  102  118  124  127 ]] 

LCA(n):  169	IfTrue	===  168  [[ 15  183 ]] #1 !jvms: TestLoopPeeling::testArrayAccess @ bci:43
n->out(0):  183	StoreI	===  169  7  181  38  [[ 184 ]]  @int[int:>=0]:exact+any *, idx=6;  Memory: @int[int:>=0]:NotNull:exact+any *, idx=6; !jvms: TestLoopPeeling::testArrayAccess @ bci:43
later(n->out(0)):  169	IfTrue	===  168  [[ 15  183 ]] #1 !jvms: TestLoopPeeling::testArrayAccess @ bci:43
n->out(0)->out(0):  184	Phi	===  15  7  7  183  7  [[ 18 ]]  #memory  Memory: @int[int:>=0]:exact+any *, idx=6; !orig=[17]
later(n->out(0)->out(0)):  15	Region	===  15  251  136  169  32  [[ 15  184  198 ]] 

idom[0]  169	IfTrue	===  168  [[ 15  183 ]] #1 !jvms: TestLoopPeeling::testArrayAccess @ bci:43
idom[1]  168	RangeCheck	===  156  167  [[ 169  172 ]] P=0.999999, C=-1.000000 !jvms: TestLoopPeeling::testArrayAccess @ bci:43
idom[2]  156	IfTrue	===  155  [[ 168  163 ]] #1 !jvms: TestLoopPeeling::testArrayAccess @ bci:43
idom[3]  155	If	===  248  96  [[ 156  157 ]] P=0.999999, C=-1.000000 !jvms: TestLoopPeeling::testArrayAccess @ bci:43
idom[4]  248	Region	===  248  247  144  [[ 248  155  259 ]] 
idom[5]  226	If	===  233  206  [[ 227  247 ]] P=0.900000, C=-1.000000 !orig=142 !jvms: TestLoopPeeling::testArrayAccess @ bci:34
idom[6]  233	IfTrue	===  232  [[ 226 ]] #1 !orig=[76] !jvms: TestLoopPeeling::testArrayAccess @ bci:11
idom[7]  232	If	===  64  74  [[ 233  251 ]] P=0.900000, C=-1.000000 !orig=[75] !jvms: TestLoopPeeling::testArrayAccess @ bci:11
idom[8]  64	IfTrue	===  54  [[ 232 ]] #1 !jvms: TestLoopPeeling::testArrayAccess @ bci:8
idom[9]  54	If	===  51  53  [[ 55  64 ]] P=0.999999, C=-1.000000 !jvms: TestLoopPeeling::testArrayAccess @ bci:8
idom[10]  51	IfTrue	===  41  [[ 54 ]] #1 !jvms: TestLoopPeeling::testArrayAccess @ bci:8
idom[11]  41	If	===  28  40  [[ 42  51 ]] P=0.999999, C=-1.000000 !jvms: TestLoopPeeling::testArrayAccess @ bci:8
idom[12]  28	IfTrue	===  27  [[ 41 ]] #1 !jvms: TestLoopPeeling::testArrayAccess @ bci:5
idom[13]  27	If	===  5  26  [[ 28  29 ]] P=0.500000, C=-1.000000 !jvms: TestLoopPeeling::testArrayAccess @ bci:5
idom[14]  5	Parm	===  3  [[ 27 ]] Control !jvms: TestLoopPeeling::testArrayAccess @ bci:-1

# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc:  SuppressErrorAt=/loopnode.cpp:3545
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/oracle/8144212/hotspot/src/share/vm/opto/loopnode.cpp:3545), pid=14004, tid=14024
#  assert(false) failed: Bad graph detected in build_loop_late
#
# JRE version: Java(TM) SE Runtime Environment (9.0) (build 1.9.0-internal-fastdebug-tohartma_2015_11_30_14_45-b00)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (1.9.0-internal-fastdebug-tohartma_2015_11_30_14_45-b00, compiled mode, tiered, compressed oops, g1 gc, linux-amd64)
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport %p %s %c %P" (or dumping to /oracle/6675699/hotspot/JTwork/scratch/core.14004)
#
# An error report file with more information is saved as:
# /oracle/6675699/hotspot/JTwork/scratch/hs_err_pid14004.log
#
# Compiler replay data is saved as:
# /oracle/6675699/hotspot/JTwork/scratch/replay_pid14004.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp


#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f6472efe274, pid=14916, tid=140068918191872
#
# JRE version: Java(TM) SE Runtime Environment (8.0_11-b12) (build 1.8.0_11-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.11-b03 compiled mode linux-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.so+0x7a1274]  PhaseIdealLoop::build_loop_late_post(Node*)+0x144
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /oracle/6675699/hotspot/JTwork/scratch/hs_err_pid14916.log
#
# Compiler replay data is saved as:
# /oracle/6675699/hotspot/JTwork/scratch/replay_pid14916.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
#
Comments
Fix verified by regression test.
07-08-2017

URL: http://hg.openjdk.java.net/jdk9/jdk9/hotspot/rev/bfb7a8a004de User: lana Date: 2016-02-10 21:55:30 +0000
10-02-2016

URL: http://hg.openjdk.java.net/jdk9/hs-comp/hotspot/rev/bfb7a8a004de User: thartmann Date: 2016-01-18 11:09:10 +0000
18-01-2016

Version 2 of the prototype fix: http://cr.openjdk.java.net/~thartmann/6675699/webrev.01/ I'm currently re-running performance measurements with the fix for JDK-8145754.
18-12-2015

Prototype fix: http://cr.openjdk.java.net/~thartmann/6675699/webrev.00/
04-12-2015

The underlying problem is that a ConvI2LNode ends up with an input that is not in its constrained type range (for example, in a peeled iteration of a loop). The node is then replaced by TOP and propagated "downwards". However, because there is no control dependency to the corresponding range check, the path from the peeled iteration that uses the result of the ConvI2L may not be eliminated. We finally crash because we are using a value that is not available (for example, from the old loop body). For details, see comments in [1]. This problem may show up for array accesses but also for other places where we emit a ConvI2L node (for example, array allocation). [1] http://cr.openjdk.java.net/~thartmann/8078262/webrev.00/test/compiler/loopopts/TestLoopPeeling.java.html
25-08-2015

Updated ILW = Crash in compiler, regression test reproduces 100%, none = HHH = P1
25-08-2015

Prototype fix that adds a CastIINode with a control edge to the range check as input to the ConvI2L node: http://cr.openjdk.java.net/~thartmann/8078262/webrev.00/
24-08-2015

Since this was defered from 7, consider backporting to 8u-release when fixed.
07-05-2014

ILW=Failing compilations, a few cases, none = MMH=P3
07-05-2014

It is very difficult problem with a lot of hidden dependencies. Work on it only when you are very familiar with C2 code.
12-04-2013

EVALUATION Initial tests indicate that using CastII introduces signifcant penalties and may not be viable. Some analysis in the loop optimizer might be required.
17-02-2010