RFR: 8365205: C2: Optimize popcount value computation using knownbits [v3]
Emanuel Peter
epeter at openjdk.org
Tue Sep 9 11:51:02 UTC 2025
On Tue, 9 Sep 2025 11:03:26 GMT, Emanuel Peter <epeter at openjdk.org> wrote:
>> Jatin Bhateja has updated the pull request incrementally with one additional commit since the last revision:
>>
>> Update countbitsnode.cpp
>
> src/hotspot/share/opto/countbitsnode.cpp line 125:
>
>> 123: range is computed using the following formulas:-
>> 124: - _hi = ~ZEROS
>> 125: - _lo = ONES
>
> Is there going to be some other Lemma here, that gives rise to the numbering? I'd just remove the numbering.
Also: this is not really a mathematical statement that can be proven, rather some sort of high-level intention.
> src/hotspot/share/opto/countbitsnode.cpp line 150:
>
>> 148: - Therefore, popcount(ONES) and popcount(~ZEROS) can safely be assumed as the upper and lower
>> 149: bounds of the result value range.
>> 150: */
>
> Suggestion:
>
> // We use the KnownBits information from the integer types to derive how many one bits
> // we have at least and at most.
> // From the definition of KnownBits, we know:
> // zeros: Indicates which bits must be 0: ones[i] =1 -> t[i]=0
> // ones: Indicates which bits must be 1: zeros[i]=1 -> t[i]=1
> //
> // From this, we derive:
> // numer_of_zeros_in_t >= pop_count(zeros)
> // -> number_of_ones_in_t <= bits_per_type - pop_count(zeros) = pop_count(~zeros)
> // number_of_ones_in_t >= pop_count(ones)
> //
> // By definition:
> // pop_count(t) = number_of_ones_in_t
> //
> // It follows:
> // pop_count(ones) <= pop_count(t) <= pop_count(~zeros)
> //
> // Note: signed _lo and _hi, as well as unsigned _ulo and _uhi bounds of the integer types
> // are already reflected in the KnownBits information, see TypeInt / TypeLong definitions.
>
> Feel free to adjust the formulation :)
It goes along the lines of what @SirYwell proposed.
> test/hotspot/jtreg/compiler/intrinsics/TestPopCountValueTransforms.java line 114:
>
>> 112: }
>> 113: return 1;
>> 114: }
>
> Thanks for the tests!
>
> I think it would be quite valuable to have some tests that do not just clamp the range, but also create random `KnownBits`, i.e. with random and/or masks.
>
> For example:
> `num = (num | ONES) & ZEROS;`
>
> And then you generate `ONES` and `ZEROS` randomly, maybe even using `Generators`?
> Then round it off with some random range comparisons at the end:
> ` if (Integer.bitCount(num) >= CON1 && Integer.bitCount(num) <= CON2) {`
Also: how many popcount instructions are left? Should it not at most be 1?
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/27075#discussion_r2333112033
PR Review Comment: https://git.openjdk.org/jdk/pull/27075#discussion_r2333226941
PR Review Comment: https://git.openjdk.org/jdk/pull/27075#discussion_r2333218115
More information about the hotspot-compiler-dev
mailing list