RFR: 8350896: Integer/Long.compress gets wrong type from CompressBitsNode::Value [v2]
Emanuel Peter
epeter at openjdk.org
Wed Apr 2 10:01:43 UTC 2025
On Wed, 2 Apr 2025 07:39:02 GMT, Jatin Bhateja <jbhateja at openjdk.org> wrote:
>> 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
>
> Jatin Bhateja has updated the pull request incrementally with one additional commit since the last revision:
>
> Review comments resolutions
@jatin-bhateja Thanks for the updates! I have a few more requests :)
src/hotspot/share/opto/intrinsicnode.cpp line 266:
> 264: if ( opc == Op_CompressBits) {
> 265: // Pattern: Integer/Long.compress(src_type, mask_type)
> 266: int max_mask_bit_width;
Suggestion:
int result_bit_width;
Is this bit width not about the result? It is really not about the mask.
Example:
`mask_type->hi_as_long() < -1L`
Here, the mask has the uppermost bit set, and so the bit width of it is the maximum 32 / 64 bits.
But we still can deduce that the result has one leading zero bit, and so the bit width of the result is either 31 or 63.
src/hotspot/share/opto/intrinsicnode.cpp line 274:
> 272: } else if (mask_type->hi_as_long() < -1L) {
> 273: // Case 2) Mask value range is less than -1, this indicates presence of at least
> 274: // one zero bit in the mask value, there by constraining the result of compression
Suggestion:
// one zero bit in the mask value, thereby constraining the result of compression
src/hotspot/share/opto/intrinsicnode.cpp line 292:
> 290: // compression result will never be a -ve value and we can safely set the
> 291: // lower bound of the result value range to zero.
> 292: lo = max_mask_bit_width == mask_bit_width ? lo : 0L;
Can you please add an assert that we are not making `lo` worse than what we already have? Someone may insert optimizations above that set `lo > 0`, and then you may lower it again here.
Suggestion:
assert(lo < 0, "we should not lower the value of lo");
lo = max_mask_bit_width == mask_bit_width ? lo : 0L;
src/hotspot/share/opto/intrinsicnode.cpp line 298:
> 296: // in case input equals above estimated lower bound.
> 297: hi = src_type->hi_as_long() == lo ? hi : src_type->hi_as_long();
> 298: hi = max_mask_bit_width < mask_bit_width ? (1L << max_mask_bit_width) - 1 : hi;
I still don't understand your comment here. For example, I don't see a `max_int` in the code... And I also don't see anything that deals with constants in the code explicitly.
And similarly as above, how do we ensure that `hi` is not raised accidentally?
src/hotspot/share/opto/intrinsicnode.cpp line 391:
> 389: return TypeInteger::zero(bt);
> 390: }
> 391:
Is this change related to the PR title? And do you have any tests for it?
test/hotspot/jtreg/compiler/c2/TestBitCompressValueTransform.java line 2:
> 1: /*
> 2: * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
Ah, I just noticed the test directory. I think we can put it in a more specific location.
test/hotspot/jtreg/compiler/c2/TestBitCompressValueTransform.java line 29:
> 27: * @library /test/lib /
> 28: * @summary C2: wrong result: Integer/Long.compress gets wrong type from CompressBitsNode::Value.
> 29: * @run main/othervm -Xbatch -XX:-TieredCompilation -XX:CompileThresholdScaling=0.3 compiler.c2.TestBitCompressValueTransform
Do you really need the flags here? The IR framework already makes sure that compilation happens, and then we execute the test again. So `Xbatch` may not be necessary to reproduce the bug. And same for `TieredCompilation`. Maybe we actually don't need any flags, but please check!
-------------
Changes requested by epeter (Reviewer).
PR Review: https://git.openjdk.org/jdk/pull/23947#pullrequestreview-2734951364
PR Review Comment: https://git.openjdk.org/jdk/pull/23947#discussion_r2024480144
PR Review Comment: https://git.openjdk.org/jdk/pull/23947#discussion_r2024462231
PR Review Comment: https://git.openjdk.org/jdk/pull/23947#discussion_r2024485135
PR Review Comment: https://git.openjdk.org/jdk/pull/23947#discussion_r2024491349
PR Review Comment: https://git.openjdk.org/jdk/pull/23947#discussion_r2024260171
PR Review Comment: https://git.openjdk.org/jdk/pull/23947#discussion_r2024257750
PR Review Comment: https://git.openjdk.org/jdk/pull/23947#discussion_r2024256227
More information about the hotspot-compiler-dev
mailing list