JDK-8323274 : C2: array load may float above range check
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 12,17,21,22,23
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2024-01-09
  • Updated: 2024-07-18
  • Resolved: 2024-02-22
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 21 JDK 23
21.0.5-oracleFixed 23 b12Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
Attached test case run with:

java -XX:-TieredCompilation -XX:-BackgroundCompilation TestArrayAccessAboveRCAfterSplitIf

fails with:

#  SIGSEGV (0xb) at pc=0x00007fd5d9056204, pid=2781800, tid=2781801
#
# JRE version: OpenJDK Runtime Environment (23.0) (slowdebug build 23-internal-adhoc.roland.jdk-jdk2)
# Java VM: OpenJDK 64-Bit Server VM (slowdebug 23-internal-adhoc.roland.jdk-jdk2, mixed mode, compressed oops, compressed class ptrs, serial gc, linux-amd64)
# Problematic frame:
# J 13 c2 TestArrayAccessAboveRCAfterSplitIf.test([I[IIIZ)I (68 bytes) @ 0x00007fd5d9056204 [0x00007fd5d90561e0+0x0000000000000024]

In that case, split if inserts a Region between a range check and a dependent array load. The array load becomes dependent on some unrelated condition after the Region is later optimized out. That unrelated condition is subsumed by a dominating identical condition and the array load floats above the range check.

I expect some other transformation can cause similar failures.
Comments
[jdk21u-fix-request] Approval Request from Martin Should get backported for parity with 21.0.5-oracle. Recognized as clean and tier 1-4 have passed.
15-06-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk21u-dev/pull/727 Date: 2024-06-14 15:28:23 +0000
14-06-2024

Changeset: 4406915e Author: Roland Westrelin <roland@openjdk.org> Date: 2024-02-22 11:07:13 +0000 URL: https://git.openjdk.org/jdk/commit/4406915ebce4266b3eb4a238382fff3c2c1d1739
22-02-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/17635 Date: 2024-01-30 16:50:08 +0000
30-01-2024

One more, this time with partial peeling: $ java -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:-TieredCompilation -XX:CompileOnly=TestArrayAccessAboveRCAfterPartialPeeling::test -XX:CompileCommand=quiet TestArrayAccessAboveRCAfterPartialPeeling [0.027s][warning][cds] The shared archive file was created by a different version or build of HotSpot # # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007f9724732152, pid=1908567, tid=1908568 # # JRE version: OpenJDK Runtime Environment (23.0) (slowdebug build 23-internal-adhoc.roland.jdk-jdk) # Java VM: OpenJDK 64-Bit Server VM (slowdebug 23-internal-adhoc.roland.jdk-jdk, mixed mode, compressed oops, compressed class ptrs, g1 gc, linux-amd64) # Problematic frame: # J 1 c2 TestArrayAccessAboveRCAfterPartialPeeling.test([IIZI)I (78 bytes) @ 0x00007f9724732152 [0x00007f9724732060+0x00000000000000f2]
24-01-2024

One more, this time when an arraycopy is turned into a series of loads/stores: $ java -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:-TieredCompilation TestArrayAccessAboveRCForArrayCopyLoad # # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007f87ec734427, pid=3456036, tid=3456037 # # JRE version: OpenJDK Runtime Environment (23.0) (slowdebug build 23-internal-adhoc.roland.jdk-jdk) # Java VM: OpenJDK 64-Bit Server VM (slowdebug 23-internal-adhoc.roland.jdk-jdk, mixed mode, compressed oops, compressed class ptrs, g1 gc, linux-amd64) # Problematic frame: # J 12 c2 TestArrayAccessAboveRCForArrayCopyLoad.test([II[IIZ)V (34 bytes) @ 0x00007f87ec734427 [0x00007f87ec734400+0x0000000000000027]
12-01-2024

Deferral Request: Old issue (not a regression) with complex fix that won't be ready in time for JDK 22 and then needs some time to stabilize.
12-01-2024

Great work coming up with these tests, [~roland]! Build search results: - TestArrayAccessAboveRCAfterUnswitching reproduces since JDK 12 - TestArrayAccessAboveRCForArrayCopyLoad reproduces since JDK 12 b14, maybe triggered by JDK-8210887 - TestArrayAccessAboveRCAfterSplitIf points to JDK-8264649 in JDK 17 b18 but that most likely just triggered it. - TestArrayAccessAboveRCAfterSinking reproduces since JDK-8274074 in JDK 18 b17 ILW = Crash in C2 compiled code because load floats above range check (result not observable), reproducible with targeted tests, -XX:-SplitIfBlocks or disable C2 compilation of affected method = HMM = P2
12-01-2024

One more similar failure. This time when a load is sunk out of loop, the load becomes dependent on a condition that's not the range check and can float above the range check: $ java -XX:-UseOnStackReplacement -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:CompileOnly=TestArrayAccessAboveRCAfterSinking::test -XX:CompileCommand=quiet TestArrayAccessAboveRCAfterSinking # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007f0014731eb3, pid=3095331, tid=3095332 # # JRE version: OpenJDK Runtime Environment (23.0) (slowdebug build 23-internal-adhoc.roland.jdk-jdk) # Java VM: OpenJDK 64-Bit Server VM (slowdebug 23-internal-adhoc.roland.jdk-jdk, mixed mode, compressed oops, compressed class ptrs, g1 gc, linux-amd64) # Problematic frame: # J 1 c2 TestArrayAccessAboveRCAfterSinking.test([Z[IIZI)I (83 bytes) @ 0x00007f0014731eb3 [0x00007f0014731e80+0x0000000000000033]
10-01-2024

Second test case crashes when run with StressGCM: $ for i in `seq 100`; do java -XX:-UseOnStackReplacement -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:+PrintCompilation -XX:CompileOnly=TestArrayAccessAboveRCAfterUnswitching::test -XX:CompileCommand=quiet -XX:+StressGCM TestArrayAccessAboveRCAfterUnswitching || break; done ... 100 1 b TestArrayAccessAboveRCAfterUnswitching::test (102 bytes) # # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007fecf8c28313, pid=2998992, tid=2998993 # # JRE version: OpenJDK Runtime Environment (23.0) (fastdebug build 23-internal-adhoc.roland.jdk-jdk) # Java VM: OpenJDK 64-Bit Server VM (fastdebug 23-internal-adhoc.roland.jdk-jdk, mixed mode, sharing, compressed oops, compressed class ptrs, g1 gc, linux-amd64) # Problematic frame: # J 1 c2 TestArrayAccessAboveRCAfterUnswitching.test([I[ZI)I (102 bytes) @ 0x00007fecf8c28313 [0x00007fecf8c282e0+0x0000000000000033] In that case, a loop is unswitched and an array load in the loop body, that has only a single use out of loop, ends up with control set to a Region that merges early exit conditions from several copies of the loop. All loop copies but one become unreachable, the last loop copy looses its back edge and the array load ends up control dependent on what was the loop early exit. That test is then replaced by a dominating identical test. That causes the array load to float above the range check. Similar issues must exist with all transformations that clone a loop body.
10-01-2024