Skip to content

Conversation

@jatin-bhateja
Copy link
Member

@jatin-bhateja jatin-bhateja commented Mar 7, 2025

Hi All,

This bugfix patch fixes incorrect value computation for Integer/Long. compress APIs.

Problems occur with a constant input and variable mask where the input's value is equal to the lower bound of the mask value., In this case, an erroneous value range estimation results in a constant value. Existing value routine first attempts to constant fold the compression operation if both input and compression mask are constant values; otherwise, it attempts to constrain the value range of result based on the upper and lower bounds of mask type.

New IR test covers the issue reported in the bug report along with a case for value range based logic pruning.

Kindly review and share your feedback.

Best Regards,
Jatin


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8350896: Integer/Long.compress gets wrong type from CompressBitsNode::Value (Bug - P2)(⚠️ The fixVersion in this issue is [25] but the fixVersion in .jcheck/conf is 26, a new backport will be created when this pr is integrated.)

Reviewers

Contributors

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/23947/head:pull/23947
$ git checkout pull/23947

Update a local copy of the PR:
$ git checkout pull/23947
$ git pull https://git.openjdk.org/jdk.git pull/23947/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 23947

View PR using the GUI difftool:
$ git pr show -t 23947

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/23947.diff

Using Webrev

Link to Webrev Comment

@jatin-bhateja
Copy link
Member Author

jatin-bhateja commented Mar 7, 2025

/label add hotspot-compiler-dev

@bridgekeeper
Copy link

bridgekeeper bot commented Mar 7, 2025

👋 Welcome back jbhateja! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Mar 7, 2025

@jatin-bhateja This change now passes all automated pre-integration checks.

ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details.

After integration, the commit message for the final commit will be:

8350896: Integer/Long.compress gets wrong type from CompressBitsNode::Value

Co-authored-by: Emanuel Peter <[email protected]>
Reviewed-by: thartmann

You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed.

At the time when this comment was updated there had been 1421 new commits pushed to the master branch:

As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details.

➡️ To integrate this PR with the above commit message to the master branch, type /integrate in a new comment.

@openjdk openjdk bot added rfr Pull request is ready for review hotspot-compiler [email protected] labels Mar 7, 2025
@openjdk
Copy link

openjdk bot commented Mar 7, 2025

@jatin-bhateja
The hotspot-compiler label was successfully added.

@mlbridge
Copy link

mlbridge bot commented Mar 7, 2025

Copy link
Contributor

@eme64 eme64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jatin-bhateja Thanks for looking into this! I left a first set of comments :)

Primarily, it is about these issues:

  • We need good comments, preferably even proofs. Because we got things wrong the last time, and there were no comments/proofs. It's difficult to get this sort of arithmetic transformation right, and it is hard to review. Proofs help to think through all the steps carefully.
  • Test coverage: I would like to see some more randomized cases of input ranges.

@jatin-bhateja
Copy link
Member Author

jatin-bhateja commented Apr 2, 2025

Hi @eme64 , I have addressed your comments, let me know if you need further clarifications.

Copy link
Contributor

@eme64 eme64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jatin-bhateja Thanks for the updates! I have a few more requests :)

@jatin-bhateja
Copy link
Member Author

jatin-bhateja commented Apr 10, 2025

Hi @eme64 , I have addressed and responded to your comments, please verify.

Copy link
Contributor

@eme64 eme64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are my responses :)

I'm still worried about updating hi and lo without some kind of assert or proof that it does not widen accidentally. I think we can prove with some effort that they do not widen currently. But then someone else comes along and modifies the code and then they might not realize the subtle proof we have in our heads currently.

And I doubt that we have good tests that would catch such regressions, if the range was suddenly a little wider than before.

Copy link
Contributor

@eme64 eme64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jatin-bhateja Thanks for the updates!
I think I now understand everything except this, so we are making good progress 😊

      // For upper bound estimation of result value range with a constant input we
      // pessimistically pick max_int value to prevent incorrect constant folding
      // in case input equals above estimated lower bound.
      hi = src_type->hi_as_long() == lo ? hi : src_type->hi_as_long();

Can you please explain it with an example, and walk me through the steps to the incorrect constant folding?

@jatin-bhateja
Copy link
Member Author

jatin-bhateja commented May 5, 2025

@jatin-bhateja Thanks for the updates! I think I now understand everything except this, so we are making good progress 😊

      // For upper bound estimation of result value range with a constant input we
      // pessimistically pick max_int value to prevent incorrect constant folding
      // in case input equals above estimated lower bound.
      hi = src_type->hi_as_long() == lo ? hi : src_type->hi_as_long();
      hi = result_bit_width < mask_bit_width ? (1L << result_bit_width) - 1 : hi;

Can you please explain it with an example, and walk me through the steps to the incorrect constant folding?

Let's assume the following

  • The input was a constant value Integer.MIN_VALUE, hence ideal type TypeInt will have both _lo and _hi set to MIN_VALUE,
  • Currently, _lo value of result value range flip b/w 0 or MIN_VALUE, lets take that to be MIN_VALUE in our case.

Earlier _hi value of the result value range was set to _hi value of the source value range.

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

If the result bit width was less than the maximum bit width of the integral type, in that case both _hi and _lo values were being set to MIN_VALUE resulting into a constant value.

@eme64
Copy link
Contributor

eme64 commented May 5, 2025

@jatin-bhateja Thanks for explaining the case with MIN_VALUE. I suppose the same could happen if lo = 0 and src_type->_hi = 0?

I would still like to see a argument/proof of line
hi = src_type->hi_as_long() == lo ? hi : src_type->hi_as_long();

Let's assume mask_type = [min_int, max_int] = int.
lo = min_int, hi = max_int before the line in question.
Now lets assume src_type = [min_int+1, -1]. So now the line in question sets hi = src_type->hi_as_long() = -1.
And the line below does not change it, because result_bit_width < mask_bit_width.
So we now have a remaining range lo = min_int, hi = -1, i.e. we return a type [min_int, -1].
But imagine at runtime we have mask_type = 0, then obviously the result is 0, which is outside the bounds!

Here the counter-example:

public class Test {
    public static int test(int src, int mask) {
        // src_type = [min_int + 1, -1]
        src = Math.max(Integer.MIN_VALUE + 1, Math.min(src, -1));
        int result = Integer.compress(src, mask);
        // The type is now calculated to be #int:<=-1
        // Hence, the test below must always be true.
        // But at runtime we only pass in mask = 0, so result should be 0.
        if (result < 0) {
            throw new RuntimeException("woopsies " + result);
        }
        return result;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 10_000; i++) {
            test(0, 0);
        }
    }
}

Running it with: ./java -Xbatch -XX:CompileCommand=compileonly,Test::test -XX:+PrintIdeal Test.java:

CompileCommand: compileonly Test.test bool compileonly = true
AFTER: print_ideal
  0  Root  === 0 42  [[ 0 1 3 23 24 37 ]] inner 
  1  Con  === 0  [[ ]]  #top
  3  Start  === 3 0  [[ 3 5 6 7 8 9 10 11 ]]  #{0:control, 1:abIO, 2:memory, 3:rawptr:BotPTR, 4:return_address, 5:int, 6:int}
  5  Parm  === 3  [[ 38 ]] Control !jvms: Test::test @ bci:-1 (line 4)
  6  Parm  === 3  [[ 38 ]] I_O !jvms: Test::test @ bci:-1 (line 4)
  7  Parm  === 3  [[ 38 ]] Memory  Memory: @BotPTR *+bot, idx=Bot; !jvms: Test::test @ bci:-1 (line 4)
  8  Parm  === 3  [[ 38 42 ]] FramePtr !jvms: Test::test @ bci:-1 (line 4)
  9  Parm  === 3  [[ 38 ]] ReturnAdr !jvms: Test::test @ bci:-1 (line 4)
 10  Parm  === 3  [[ 25 ]] Parm0: int !jvms: Test::test @ bci:-1 (line 4)
 11  Parm  === 3  [[ 27 ]] Parm1: int !jvms: Test::test @ bci:-1 (line 4)
 23  ConI  === 0  [[ 26 ]]  #int:min+1
 24  ConI  === 0  [[ 25 ]]  #int:-1
 25  MinI  === _ 10 24  [[ 26 ]]  !jvms: Test::test @ bci:4 (line 4)
 26  MaxI  === _ 23 25  [[ 27 ]]  !jvms: Test::test @ bci:7 (line 4)
 27  CompressBits  === _ 26 11  [[ 38 ]]  #int:<=-1:www !jvms: Test::test @ bci:13 (line 5)
 37  ConI  === 0  [[ 38 ]]  #int:22
 38  CallStaticJava  === 5 6 7 8 9 (37 1 1 27 ) [[ 39 ]] # Static uncommon_trap(reason='unloaded' action='reinterpret' index='22' debug_id='0')  void ( int ) C=0.000100 Test::test @ bci:21 (line 10) !jvms: Test::test @ bci:21 (line 10)
 39  Proj  === 38  [[ 42 ]] #0 !jvms: Test::test @ bci:21 (line 10)
 42  Halt  === 39 1 1 8 1  [[ 0 ]]  !jvms: Test::test @ bci:21 (line 10)
Exception in thread "main" java.lang.RuntimeException: woopsies 0
	at Test.test(Test.java:10)
	at Test.main(Test.java:17)

You can see the the exception is wrongly thrown, and you can see the wrong type of the CompressBits.

If I run it in intepreter only, I do not see the exception: ./java -Xbatch -XX:CompileCommand=compileonly,Test::test -XX:+PrintIdeal -Xint Test.java


We got this code wrong before, and now again. How can we gain confidence that it will be correct on the next attempt?

My Opinion?
I really want to see a solid proof of this code. Because it is so easy to get these things wrong. And it seems our tests are also not good enough to catch this. So we obviously need better tests too.

@eme64
Copy link
Contributor

eme64 commented May 5, 2025

@jatin-bhateja Well, KnownBits will only make testing more difficult, it does not remove challenges, rather increases the challenges. At that point we do not only have to test constants, and ranges, but also all sorts of bit patterns.

@eme64
Copy link
Contributor

eme64 commented May 5, 2025

Let me tune this check and update the test.

For me to approve this code, you will have to do more than that. I will need:

  • Proof of the implemented logic.
  • More tests.

@merykitty
Copy link
Member

merykitty commented May 5, 2025

@jatin-bhateja This operation is non-trivial, I expect the level of coverage to be on par with #23089. If you want to have a quick fix, I suggest removing all the logic and simply returning the bottom type.

@jatin-bhateja
Copy link
Member Author

jatin-bhateja commented May 5, 2025

@jatin-bhateja Well, KnownBits will only make testing more difficult, it does not remove challenges, rather increases the challenges. At that point we do not only have to test constants, and ranges, but also all sorts of bit patterns.

@eme64 , glad you are picking that up. I don't want to comment on KnownBits on this PR I will add my review suggestions on #17508, Need a lil time to refresh memory, but we are excited to contribute to it.

I think for this bug fix, its better to be safe for now, let me update the revision and test.

@jatin-bhateja
Copy link
Member Author

jatin-bhateja commented May 5, 2025

Hi @eme64 , can you kindly run this latest version through your testing, please.

@eme64
Copy link
Contributor

eme64 commented May 6, 2025

@jatin-bhateja I think I'd rather wait until you have more thorough testing and the proofs I asked for, otherwise I would need to run the testing twice ;)

@jatin-bhateja
Copy link
Member Author

jatin-bhateja commented May 6, 2025

@jatin-bhateja I think I'd rather wait until you have more thorough testing and the proofs I asked for, otherwise I would need to run the testing twice ;)

I have added comments in the code which give sufficient details, let me know if you still need more explanation

@jatin-bhateja
Copy link
Member Author

Quick note on C2 Integral types:-

  • Integral types now encapsulate 3 lattice structures perf TypeInt/Long, namely signed, unsigned and knownbits.
  • All three lattice values are in sync post-canonicalization.
  • Lattice is a partial order relation, i.e., reflexive, transitive but anti-symmetric.
  • An integral lattice contains two special values: a TOP (no value, no assumption can be drawn by the compiler)
    and BOTTOM (all possible values in the value range)

Verification ensures that the lattice is symmetrical around the centerline, i.e., a semi-lattice.

  • For a symmetrical lattice, only one operation i.e., meet/join is sufficient for value resolution; other operations can be computed
    by taking the dual of the first one using de-Morgan's law.

    join = Dual (meet (dual(type1), dual(type2))

  • In theory, meet b/w two lattice points takes us to the greatest lower bound in the Hesse diagram,
    while join b/w two lattice points takes us to the lowest upper bound. Also, TOP represents the entire value range of the
    lattice, while BOTTOM represents no value, but C2 follows an inverted lattice convention.

Inverted integral lattice hasse diagram

   
                       TOP (no value)
                    /  | | \
                 -MIN …….. MAX
                     \ | | /
                     BOTTOM (all possible values)


  • Thus, a MEET of two lattice points takes us to the greatest upper bound of the lattice structure; in this case, it's the union of
    two lattice points i.e., we pick the minimum of the lower bounds and max of the upper bounds of participating lattice points.
    JOIN takes us to the lowest upper-bound lattice points of the inverted lattice structure. in this case, it will be an intersection of
    lattice points, which constrains the value range i.e., we pick the max of the lower bounds and the minimum of the upper
    bounds of the two participating integral lattice points.

e.g., if TypeInt t1 = {lo:10, hi:100} and TypeInt t2 = {lo:1, hi:20}, then
t1.meet(t2) = lowest upper bound.
= { lo = min(t1.lo, t2.lo}, hi = max(t1.hi , t2.hi}}
= { lo = min(10, 1), hi = max(100, 20)}
= { lo = 1, hi = 100}

  t1.join(t2) = dual (meet (dual(t1), dual(t2))
    where dual = {lo : hi} => {hi : lo}
    = dual (meet (dual {lo : 10, hi : 100}, dual {lo : 1, hi : 20}})
    = dual (meet ({lo: 100, hi : 10}}, {lo:20: , hi:1})
    = dual (min(t1.lo, t2.lo}, max(t1.hi, t2.hi})
    = dual (min(100, 20), max(10, 1))
    = dual (lo:20, hi:10}
    = (lo : 10, hi : 20)

  Additional identities 👎
  • TOP meet VAL = VAL since we cannot move to any other greatest lower bound when one of the inputs is TOP (unknown value), to move to the greatest lower bound both the inputs must be known values.

  • BOTTOM meet VAL = BOTTOM

    Now, some quick notes on CCP

  • Optimistic data flow analysis using ROPT walk on the ideal graph.

  • Each lattice begins with a TOP value, and analysis progressively adds elements to the lattice. Analysis expects to expand the
    value range with each data flow iteration, thereby monotonically increasing the lattice set.

  • After each value transformation, type verification checks that the new value is greater than the old value in the lattice, in other
    words new value should dominate the old value in the hasse diagram of the lattice. Thus, tnew->meet(told) gives us the
    lowest upper bound of two lattice points, i.e., tnew should be a superset of told. CCP is an optimistic iterative data flow
    analysis which traverses the ideal graph in RPOT order and reaches a fixed point once value transforms as no side-effects on
    the graph.

@jatin-bhateja
Copy link
Member Author

Hi @TobiHartmann . Please let me know if it's good to land in.

@TobiHartmann
Copy link
Member

Thanks, testing looks good now! I'm out for the rest of the week and can review only next week.

Copy link
Member

@TobiHartmann TobiHartmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me and I think you addressed all the comments that Emanuel had. Let's wait for another day or two in case someone else wants to take a look as well.

In the meantime, please request approval for integration into JDK 25 since we are know at RDP 2:
https://openjdk.org/jeps/3#Fix-Request-Process

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Jul 21, 2025
@vnkozlov
Copy link
Contributor

vnkozlov commented Jul 21, 2025

I am not sure about JDK 25 approval for these changes.

Can you do simple fix for JDK 25 as @merykitty suggested: "I suggest removing all the logic and simply returning the bottom type" ? Will it be the same complexity? Will it affect performance (and how much)?

Copy link
Member Author

@jatin-bhateja jatin-bhateja left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @kvn, Apart from couple of lines of fix, patch mainly re-structured existing handling and added additional comments and proofs along with an exhaustive test.

Will it be the same complexity? Will it affect performance (and how much)?

Effective code changes are very minimal, in general value-constracting optimizations can prune the control paths or constant fold dependent expressions, thereby reducing the JIT code size, which has other side effects on inlining decisions. For infrequently taken paths, C2 anyway injects Uncommon traps.

Should I check this into jdk-mainline and then prepare minimal fix without comments / re-structuring (if needed) for jdk25u?

@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Jul 22, 2025
@jatin-bhateja
Copy link
Member Author

This looks good to me and I think you addressed all the comments that Emanuel had. Let's wait for another day or two in case someone else wants to take a look as well.

In the meantime, please request approval for integration into JDK 25 since we are know at RDP 2: https://openjdk.org/jeps/3#Fix-Request-Process

Hi @TobiHartmann, Can you please re-verify the latest version of patch and approve if all tests are green.

@TobiHartmann
Copy link
Member

Hi @TobiHartmann, Can you please re-verify the latest version of patch and approve if all tests are green.

Sure, I'll re-run testing. How did you find the issue that you fixed in the latest commit?

@TobiHartmann
Copy link
Member

@vnkozlov Given that this is an old issue already affecting JDK 19, maybe we should just defer to JDK 26 for now and then backport to JDK 25u only once the fix is stable?

@vnkozlov
Copy link
Contributor

@vnkozlov Given that this is an old issue already affecting JDK 19, maybe we should just defer to JDK 26 for now and then backport to JDK 25u only once the fix is stable?

Yes, I agree. Please replace fix request with defer request in JBS bug report.

@jatin-bhateja
Copy link
Member Author

jatin-bhateja commented Jul 23, 2025

Hi @TobiHartmann, Can you please re-verify the latest version of patch and approve if all tests are green.

Sure, I'll re-run testing. How did you find the issue that you fixed in the latest commit?

Hi @TobiHartmann , On a re-review I found this incompatibility between code and comments, its not a correctness issue but trying to constrain the result value range further :-)

Hi @vnkozlov ,

On performance front, I see 500x improvement with and without patch for following micro.

{C9168262-BEFD-43FE-A2DF-E935FA312A41} {60D7988B-3DBC-4C84-AC13-68E858360045}

public class test_compress {

   public static int micro(int src, int mask) {
       src = Math.max(0, Math.min(5, src));
       int cond = Integer.compress(src, mask);
       if (cond < 0) {
           throw new AssertionError("Unexpected control path");
       }
       return cond;
   }

   public static void main(String [] args) {
       int res = 0;
       for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
           res = micro(i, i);
       }
       long t1 = System.currentTimeMillis();
       for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
           res = micro(i, i);
       }
       long t2 = System.currentTimeMillis();
       System.out.println("[time]  " + (t2-t1) + " ms [res] " + res);
   }
}
Baseline:
 Performance counter stats for '/mnt/c/GitHub/lworld/valhalla/build/linux-x86_64-server-slowdebug/images/jdk//bin/java -Xbatch -XX:-TieredCompilation -XX:CompileCommand=Print,test_compress::micro -cp . test_compress':

           5289.35 msec task-clock                       #    0.951 CPUs utilized             
              2112      context-switches                 #  399.293 /sec                      
                10      cpu-migrations                   #    1.891 /sec                      
             21505      page-faults                      #    4.066 K/sec                     
       24329079894      cycles                           #    4.600 GHz                       
        1319976188      stalled-cycles-frontend          #    5.43% frontend cycles idle      
       84815338636      instructions                     #    3.49  insn per cycle            
                                                  #    0.02  stalled cycles per insn   
       10705823114      branches                         #    2.024 G/sec                     
          19154969      branch-misses                    #    0.18% of all branches           

       5.563498818 seconds time elapsed

       5.011463000 seconds user
       0.251171000 seconds sys

Withopt:
========
 Performance counter stats for '/mnt/c/GitHub/jdk/build/linux-x86_64-server-slowdebug/images/jdk//bin/java -Xbatch -XX:-TieredCompilation -XX:CompileCommand=Print,test_compress::micro -cp . test_compress':

            663.70 msec task-clock                       #    0.816 CPUs utilized             
              1462      context-switches                 #    2.203 K/sec                     
                 4      cpu-migrations                   #    6.027 /sec                      
             14566      page-faults                      #   21.947 K/sec                     
        2672604843      cycles                           #    4.027 GHz                       
        1014349463      stalled-cycles-frontend          #   37.95% frontend cycles idle      
        4151688716      instructions                     #    1.55  insn per cycle            
                                                  #    0.24  stalled cycles per insn   
         819204263      branches                         #    1.234 G/sec                     
          14530718      branch-misses                    #    1.77% of all branches           

       0.813760237 seconds time elapsed

       0.460724000 seconds user
       0.183508000 seconds sys


Path length i.e. dynamic instruction count is significantly more with baseline.

Copy link
Member

@TobiHartmann TobiHartmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still looks good to me. I'll re-run testing with the latest changes. @jatin-bhateja could you please adjust your "Fix request" comment in JBS to be a "Defer request", see https://openjdk.org/jeps/3#Bug-Deferral-Process

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Jul 23, 2025
@TobiHartmann
Copy link
Member

Testing is all clean. I think this is good to go into JDK 26.

@jatin-bhateja
Copy link
Member Author

/integrate

@jatin-bhateja
Copy link
Member Author

Testing is all clean. I think this is good to go into JDK 26.

Thanks @TobiHartmann , integrating it.

@openjdk
Copy link

openjdk bot commented Jul 23, 2025

Going to push as commit b02c125.
Since your change was applied there have been 1426 commits pushed to the master branch:

Your commit was automatically rebased without conflicts.

@openjdk openjdk bot added the integrated Pull request has been integrated label Jul 23, 2025
@openjdk openjdk bot closed this Jul 23, 2025
@openjdk openjdk bot removed ready Pull request is ready to be integrated rfr Pull request is ready for review labels Jul 23, 2025
@openjdk
Copy link

openjdk bot commented Jul 23, 2025

@jatin-bhateja Pushed as commit b02c125.

💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored.

@vnkozlov
Copy link
Contributor

Thank you, @jatin-bhateja , for providing performance numbers.
I approved deference request.

Copy link
Contributor

@eme64 eme64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jatin-bhateja @vnkozlov @TobiHartmann
The TemplateFramework fuzzer found a bug in this bugfix:
#28062

It is quite subtle, and would have been hard to spot in the review. But we could have done a better job with tests.

// result.lo = 0
if (maskcon != -1L) {
int bitcount = population_count(static_cast<julong>(bt == T_INT ? maskcon & 0xFFFFFFFFL : maskcon));
hi = (1UL << bitcount) - 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace 1UL -> 1ULL for Windows.

// Rule 3:
// We can further constrain the upper bound of bit compression if the number of bits
// which can be set(one) is less than the maximum number of bits of integral type.
hi = MIN2((jlong)((1UL << result_bit_width) - 1L), hi);
Copy link
Contributor

@eme64 eme64 Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replace 1UL -> 1ULL for Windows.

Comment on lines +540 to +541
src = Math.max(BOUND_LO_L, Math.min(src, BOUND_HI_L));
long res = Long.compress(src, mask);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and in all other similar tests:
It seems we are only creating "random input ranges" for src, and not for mask. Bummer ☹️

@jatin-bhateja jatin-bhateja deleted the JDK-8350896 branch October 31, 2025 06:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

hotspot-compiler [email protected] integrated Pull request has been integrated

Development

Successfully merging this pull request may close these issues.

7 participants