JDK-8350896 : Integer/Long.compress gets wrong type from CompressBitsNode::Value
  • Type: Bug
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 19,21,24,25
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2025-02-27
  • Updated: 2025-10-31
  • Resolved: 2025-07-23
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 26
26 b08Fixed
Related Reports
Causes :  
Causes :  
Causes :  
Relates :  
Description
I found this during work with the Template Framework JDK-8344942.

[~thartmann] found it was a regression of JDK-8283894, which was my suspicion after tracing it back to code in CompressBitsNode::Value and more specifically bitshuffle_value, on this line:

hi = mask_max_bw < max_bw ? (1L << mask_max_bw) - 1 : src_type->hi_as_long();

Reproduce the result like this:

java -Xbatch -XX:CompileCommand=compileonly,Test::test -XX:+PrintIdeal Test.java
CompileCommand: compileonly Test.test bool compileonly = true
AFTER: print_ideal
  0  Root  === 0 28  [[ 0 1 3 21 ]] inner 
  3  Start  === 3 0  [[ 3 5 6 7 8 9 ]]  #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address}
  5  Parm  === 3  [[ 28 ]] Control !jvms: Test::test @ bci:-1 (line 26)
  6  Parm  === 3  [[ 28 ]] I_O !jvms: Test::test @ bci:-1 (line 26)
  7  Parm  === 3  [[ 28 ]] Memory  Memory: @BotPTR *+bot, idx=Bot; !jvms: Test::test @ bci:-1 (line 26)
  8  Parm  === 3  [[ 28 ]] FramePtr !jvms: Test::test @ bci:-1 (line 26)
  9  Parm  === 3  [[ 28 ]] ReturnAdr !jvms: Test::test @ bci:-1 (line 26)
 21  ConI  === 0  [[ 28 ]]  #int:min
 28  Return  === 5 6 7 8 9 returns 21  [[ 0 ]] 
Exception in thread "main" java.lang.RuntimeException: Bad value: -2147483648 0
	at Test.main(Test.java:36)

We can see from the PrintIdeal, that the Integer.compress has been constant folded to the wrong value.


------------------------------------------------------------- The identical issue exists for long:

./java -Xbatch -XX:CompileCommand=compileonly,TestL::test -XX:+PrintIdeal TestL.java
CompileCommand: compileonly TestL.test bool compileonly = true
AFTER: print_ideal
  0  Root  === 0 28  [[ 0 1 3 21 ]] inner 
  3  Start  === 3 0  [[ 3 5 6 7 8 9 ]]  #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address}
  5  Parm  === 3  [[ 28 ]] Control !jvms: TestL::test @ bci:-1 (line 7)
  6  Parm  === 3  [[ 28 ]] I_O !jvms: TestL::test @ bci:-1 (line 7)
  7  Parm  === 3  [[ 28 ]] Memory  Memory: @BotPTR *+bot, idx=Bot; !jvms: TestL::test @ bci:-1 (line 7)
  8  Parm  === 3  [[ 28 ]] FramePtr !jvms: TestL::test @ bci:-1 (line 7)
  9  Parm  === 3  [[ 28 ]] ReturnAdr !jvms: TestL::test @ bci:-1 (line 7)
 21  ConL  === 0  [[ 28 ]]  #long:min
 28  Return  === 5 6 7 8 9 returns 21  [[ 0 ]] 
Exception in thread "main" java.lang.RuntimeException: Bad value: -9223372036854775808 0
	at TestL.main(TestL.java:17)
Comments
Is it time to bring the fix to 25u?
16-09-2025

Changeset: b02c1256 Branch: master Author: Jatin Bhateja <jbhateja@openjdk.org> Date: 2025-07-23 13:31:15 +0000 URL: https://git.openjdk.org/jdk/commit/b02c1256768bc9983d4dba899cd19219e11a380a
23-07-2025

Deferral Request Bug fix significantly re-factored existing value optimization for compress/expand APIs, while effective code change is small, to mitigate any risk of introducing a new issue at this point, we seek approval to defer this bugfix to JDK-26. We plan to backport the fix to jdk25u after through validation.
23-07-2025

Fix request NMI The changes are complex and not tested in full yet. In PR I asked about to bailout the optimization for JDK 25 instead of back porting whole fix.
21-07-2025

Fix request for RDP2 Scope of the problem is limited to incorrect value computation of bit expansion and compression APIs (Integer/Long.compress/expand). New value transforms with detailed proofs and comments fixes existing loopholes. An exhaustive test case[1] has been added along with the patch under review[2] to cover various scenarios for constant folding by constraining the value ranges of mask and source inputs. Given that the problem has a limited scope but relates to very useful Java SE APIs we seek approval to integrate it in RDP2 of JDK-25. Patch has received one approval from [~thartmann] [1] https://github.com/openjdk/jdk/pull/23947/files#diff-17ba17a1878829111f1bf6411f7b23b846d1d4f3d94deb884b56588fa87316f7 [2] https://github.com/openjdk/jdk/pull/23947
21-07-2025

Even "simple" partial evaluation expressions in C2 methods are subject to hidden flaws due to C++ UB surprises. This is why, some day, I think all C2 compile-time arithmetic should be performed by a separately curated arithmetic engine. Not be ad hoc C++ expressions mixed into the optimizer. By "arithmetic" I include arithmetic not only against single values, but also against subsets of their types, when those subsets are relevant to C2. That includes signed min/max ranges, and probably unsigned umin/umax ranges, and/or bitwise up/down masks. Most of the relevant formulas are well-known and testable, and have been on the record for a long time. By "separately curated" I mean a C++ interface (for long and its subranges at least) which is sepaartely reviewed by arithmetic experts, and separately stress-tested (for all corner cases) by a gtest (in jtreg format in the source repo).
03-06-2025

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/23947 Date: 2025-03-07 17:37:36 +0000
07-03-2025

Bit compressing an integral value squeezes bits corresponding to the set mask bits. Here, we have a limiting case of constant input and variable mask where input is the min_integral value and range computation results into assignment of min_integral value to both the delimiting values, i.e., TypeInt.lo and TypeInt.hi and thus resulting into incorrect constant folding.
05-03-2025

Thanks [~thartmann] I will take a look
04-03-2025

[~sviswanathan], [~jbhateja], could you please have a look?
28-02-2025

ILW = Incorrect result of C2 compiled code, easy to reproduce but edge case, -XX:DisableIntrinsic=_compress_i,_compress_l = HML = P2
28-02-2025