JDK-8330819 : C2 SuperWord: bad dominance after pre-loop limit adjustment with base that has CastLL after pre-loop
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 20,21,22,23
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2024-04-22
  • Updated: 2024-06-18
  • Resolved: 2024-04-24
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 b20Fixed
Related Reports
Blocks :  
Relates :  
Relates :  
Description
I can reproduce it like this:

JDK23:
./java -XX:CompileCommand=compileonly,Test*::* -XX:CompileCommand=TraceAutoVectorization,Test*::*,SW_REJECTIONS,POINTERS,ALIGN_VECTOR -XX:+TraceNewVectors -Xbatch -XX:+TraceLoopOpts TestMemorySegmentMainLoopAlignment.java


JDK21:
/oracle-work/jdk-21.0.3/fastdebug/bin/java --enable-preview --source 21 -XX:CompileCommand=compileonly,Test*::* -XX:+TraceNewVectors -Xbatch -XX:+TraceLoopOpts TestMemorySegmentMainLoopAlignment.java

JDK20: reproducer does not compile, because MemorySegment API was different.

It is possible that with VarHandle or Unsafe this might fail with even older JDK's.


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

VLoopVPointers::print:
  VPointer[mem: 1633      LoadI, base:    1, adr: 1669,  base[   1] + offset(   4) + invar(   0) + scale(   4) * iv]
  VPointer[mem: 1639      LoadI, base:   65, adr:   65,  base[  65] + offset(  20) + invar[1149] + scale(   4) * iv]
  VPointer[mem: 1645      LoadI, base:   65, adr:   65,  base[  65] + offset(  16) + invar[1149] + scale(   4) * iv]
  VPointer[mem: 1470      LoadI, base:   65, adr:   65,  base[  65] + offset(  24) + invar[1149] + scale(   4) * iv]
  VPointer[mem:  873      LoadI, base:   65, adr:   65,  base[  65] + offset(  28) + invar[1149] + scale(   4) * iv]
  VPointer[mem: 1648      LoadI, base:    1, adr: 1669,  base[   1] + offset(   0) + invar(   0) + scale(   4) * iv]
  VPointer[mem: 1465      LoadI, base:    1, adr: 1669,  base[   1] + offset(   8) + invar(   0) + scale(   4) * iv]
  VPointer[mem:  781      LoadI, base:    1, adr: 1669,  base[   1] + offset(  12) + invar(   0) + scale(   4) * iv]

SuperWord::transform_loop:
      Loop: N1657/N886  counted [int,int),+4 (17 iters)  main has_sfpt strip_mined
 1657  CountedLoop  === 1657 1181 886  [[ 1633 1637 1648 1657 1658 1465 781 1177 ]] inner stride: 4 main of N1657 strip mined !orig=[1476],[1182],[1030],[921],[912],[117] !jvms: TestMemorySegmentMainLoopAlignment::test @ bci:23 (line 27)
SuperWord::output          Loop: N1657/N886  counted [int,int),+4 (17 iters)  main has_sfpt strip_mined

adjust_pre_loop_limit_to_align_main_loop_vectors:
  align_to_ref: 1648  LoadI  === 1657 63 1711  [[ 1644 ]]  @rawptr:BotPTR, idx=Raw; unaligned unsafe #int (does not depend only on test, unknown control) !orig=1465,781 !jvms: Unsafe::getIntUnaligned @ bci:5 (line 3576) ScopedMemoryAccess::getIntUnalignedInternal @ bci:15 (line 1893) ScopedMemoryAccess::getIntUnaligned @ bci:6 (line 1881) VarHandleSegmentAsInts::get @ bci:48 (line 108) VarHandleGuards::guard_LJ_I @ bci:49 (line 999) AbstractMemorySegmentImpl::get @ bci:8 (line 772) TestMemorySegmentMainLoopAlignment::memorySegmentGet @ bci:12 (line 19) 0x0000000039228418::apply @ bci:4 TestMemorySegmentMainLoopAlignment::test @ bci:30 (line 27)
  aw:       16
  stride:   4
  scale:    4
  offset:   0
  base: 1669  CastX2P  === _ 1590  [[ 1715 1707 1709 1711 ]]  !orig=[1671]
  invar:     null
  old_limit:    32  ConI  === 0  [[ 1705 1270 1149 1265 1405 1430 1712 1686 1551 1289 1325 1354 1642 1381 1653 1679 ]]  #int:2
  orig_limit:  1015  SubI  === _ 25 1012  [[ 1430 1162 1276 1306 ]]  !orig=[1017]
  AW = aw(16) / abs(scale(4)) = 4
  xboi:    31  ConI  === 0  [[ 48 1012 1028 1179 80 984 1274 1272 80 80 ]]  #int:0
  xbase:  1729  CastP2X  === _ 1669  [[ ]] 
  xbase:  1730  ConvL2I  === _ 1729  [[ ]]  #int
  xboi:  1731  SubI  === _ 31 1730  [[ ]] 
  log2_abs_scale:    32  ConI  === 0  [[ 1705 1270 1149 1265 1405 1430 1712 1686 1551 1289 1325 1354 1642 1381 1653 1679 1732 ]]  #int:2
  XBOI:  1732  URShiftI  === _ 1731 32  [[ ]] 
  XBOI_OP_old_limit:  1733  SubI  === _ 1732 32  [[ ]] 
  mask_AW:  1718  ConI  === 0  [[ 1474 1734 ]]  #int:3
  adjust_pre_iter:  1734  AndI  === _ 1733 1718  [[ ]] 
  new_limit:  1735  AddI  === _ 32 1734  [[ ]] 
  constrained_limit:  1736  MinI  === _ 1735 1015  [[ ]] 
TraceNewVectors [SuperWord]:  1737  LoadVector  === 1001 63 1646  [[ 1644 1632 1464 874 ]]  @int[int:16] (java/lang/Cloneable,java/io/Serializable):NotNull:exact+any *, idx=6; mismatched #vectorx[4]:{int} !orig=[1645],[1470],[873] !jvms: TestMemorySegmentMainLoopAlignment::test @ bci:39 (line 27)
TraceNewVectors [SuperWord]:  1738  LoadVector  === 1657 63 1711  [[ 1644 1632 1464 874 ]]  @rawptr:BotPTR, idx=Raw; mismatched #vectorx[4]:{int} (does not depend only on test, unknown control) !orig=[1648],[1465],[781] !jvms: Unsafe::getIntUnaligned @ bci:5 (line 3576) ScopedMemoryAccess::getIntUnalignedInternal @ bci:15 (line 1893) ScopedMemoryAccess::getIntUnaligned @ bci:6 (line 1881) VarHandleSegmentAsInts::get @ bci:48 (line 108) VarHandleGuards::guard_LJ_I @ bci:49 (line 999) AbstractMemorySegmentImpl::get @ bci:8 (line 772) TestMemorySegmentMainLoopAlignment::memorySegmentGet @ bci:12 (line 19) 0x0000000039228418::apply @ bci:4 TestMemorySegmentMainLoopAlignment::test @ bci:30 (line 27)
TraceNewVectors [SuperWord]:  1739  AddVI  === _ 1737 1738  [[ 1643 1631 1463 875 ]]  #vectorx[4]:{int} !orig=[1644],[1464],[874] !jvms: TestMemorySegmentMainLoopAlignment::test @ bci:40 (line 27)
TraceNewVectors [SuperWord]:  1740  AddReductionVI  === _ 1658 1739  [[ 1658 1183 1338 ]]  !orig=[1643],[1463],[875],1485 !jvms: TestMemorySegmentMainLoopAlignment::test @ bci:41 (line 27)

SuperWord::transform_loop: success
TraceNewVectors [UnorderedReduction]:  1741  Replicate  === _ 31  [[ ]]  #vectorx[4]:{int}
TraceNewVectors [UnorderedReduction]:  1742  AddVI  === _ 1658 1739  [[ 1338 1183 1658 ]]  #vectorx[4]:{int} !orig=[1740],[1643],[1463],[875],1485 !jvms: TestMemorySegmentMainLoopAlignment::test @ bci:41 (line 27)
TraceNewVectors [UnorderedReduction]:  1743  AddReductionVI  === _ 1313 1742  [[ 1338 1183 ]] 
Bad graph detected in compute_lca_of_uses
n:  1311  Bool  === _ 1312  [[ 1329 ]] [lt] !orig=1176,[1027]
early(n):  1348  IfTrue  === 1347  [[ 1513 1492 1363 ]] #1
n->in(1):  1312  CmpI  === _ 1324 1430  [[ 1311 ]]  !orig=1175,[1026]
early(n->in(1)):  1348  IfTrue  === 1347  [[ 1513 1492 1363 ]] #1
n->in(1)->in(1):  1324  AddI  === _ 1328 44  [[ 1312 1328 1340 1345 ]]  !orig=1174,[1025]
early(n->in(1)->in(1)):  1326  CountedLoop  === 1326 1206 1330  [[ 1315 1326 1328 1329 1331 ]] inner stride: 1 pre of N1182 !orig=[1182],[1030],[921],[912],[117] !jvms: TestMemorySegmentMainLoopAlignment::test @ bci:23 (line 27)
n->in(1)->in(2):  1430  Opaque1  === _ 1736 1015  [[ 1312 ]] 
early(n->in(1)->in(2)):  1348  IfTrue  === 1347  [[ 1513 1492 1363 ]] #1

LCA(n):  1326  CountedLoop  === 1326 1206 1330  [[ 1315 1326 1328 1329 1331 ]] inner stride: 1 pre of N1182 !orig=[1182],[1030],[921],[912],[117] !jvms: TestMemorySegmentMainLoopAlignment::test @ bci:23 (line 27)
n->out(0):  1329  CountedLoopEnd  === 1326 1311  [[ 1330 1343 ]] [lt] P=0.500000, C=18415.000000 !orig=1177,[1031],[1007],[918]
n->out(0)->out(0):  1330  IfTrue  === 1329  [[ 1326 ]] #1 !orig=886 !jvms: TestMemorySegmentMainLoopAlignment::test @ bci:20 (line 26)
n->out(0)->out(1):  1343  IfFalse  === 1329  [[ 1347 ]] #0

idoms of early "1348 IfTrue":
idom[3]:   1326  CountedLoop
idom[2]:   1329  CountedLoopEnd
idom[1]:   1343  IfFalse
idom[0]:   1347  If
n:         1348  IfTrue

idoms of (wrong) LCA "1326 CountedLoop":
n:         1326  CountedLoop

Real LCA of early "1348 IfTrue" (idom[3]) and wrong LCA "1326 CountedLoop":
 1326  CountedLoop  === 1326 1206 1330  [[ 1315 1326 1328 1329 1331 ]] inner stride: 1 pre of N1182 !orig=[1182],[1030],[921],[912],[117] !jvms: TestMemorySegmentMainLoopAlignment::test @ bci:23 (line 27)

*** Use 1326 isn't dominated by def 1311 ***
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  Internal Error (/oracle-work/jdk-fork2/open/src/hotspot/share/opto/loopnode.cpp:5901), pid=1708090, tid=1708104
#  assert(!had_error) failed: bad dominance
#
# JRE version: Java(TM) SE Runtime Environment (23.0) (fastdebug build 23-internal-2024-04-05-0704446.emanuel...)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (fastdebug 23-internal-2024-04-05-0704446.emanuel..., mixed mode, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64)
# Problematic frame:
# V  [libjvm.so+0x129be37]  PhaseIdealLoop::compute_lca_of_uses(Node*, Node*, bool)+0x987
#
# Core dump will be written. Default location: Core dumps may be processed with "/usr/share/apport/apport -p%p -s%s -c%c -d%d -P%P -u%u -g%g -- %E" (or dumping to /oracle-work/jdk-fork2/build/linux-x64-debug/jdk/bin/core.1708090)
#
# An error report file with more information is saved as:
# /oracle-work/jdk-fork2/build/linux-x64-debug/jdk/bin/hs_err_pid1708090.log
#
# Compiler replay data is saved as:
# /oracle-work/jdk-fork2/build/linux-x64-debug/jdk/bin/replay_pid1708090.log
#
# If you would like to submit a bug report, please visit:
#   https://bugreport.java.com/bugreport/crash.jsp
#
Aborted (core dumped)

Comments
A pull request was submitted for review. URL: https://git.openjdk.org/jdk21u-dev/pull/744 Date: 2024-06-18 15:04:09 +0000
18-06-2024

Changeset: e681e9b4 Author: Emanuel Peter <epeter@openjdk.org> Date: 2024-04-24 08:45:32 +0000 URL: https://git.openjdk.org/jdk/commit/e681e9b4d78c57d031e08e11dfa6250d1f52f5f5
24-04-2024

ILW = Assert during C2 compilation due to bad dominance, reproducible but edge case, disable superword or compilation of affected method = HLM = P3
23-04-2024

[~epeter], I narrowed it down to JDK-8288022 in JDK 20 b06.
23-04-2024

A pull request was submitted for review. URL: https://git.openjdk.org/jdk/pull/18892 Date: 2024-04-22 15:53:42 +0000
23-04-2024

I was able to transform the case to not use MemorySegment, but Unsafe instead. /oracle-work/jdk-20.0.2/fastdebug/bin/java --add-modules java.base --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/jdk.internal.util=ALL-UNNAMED -XX:CompileCommand=compileonly,Test*::* -Xbatch -XX:+TraceLoopOpts TestMemorySegmentMainLoopAlignmentUnsafe.java It would be nice to run build-search with this one.
22-04-2024