RFR: 8350896: Integer/Long.compress gets wrong type from CompressBitsNode::Value [v13]
Jatin Bhateja
jbhateja at openjdk.org
Mon Jul 14 12:20:46 UTC 2025
On Tue, 3 Jun 2025 13:30:05 GMT, Emanuel Peter <epeter at openjdk.org> wrote:
>> src/hotspot/share/opto/intrinsicnode.cpp line 241:
>>
>>> 239: jlong lo = bt == T_INT ? min_jint : min_jlong;
>>> 240:
>>> 241: if(mask_type->is_con() && mask_type->get_con_as_long(bt) != -1L) {
>>
>> Now you removed the condition `mask_type->get_con_as_long(bt) != -1L`. Do you know why it was there in the first place?
>>
>> It seems to me that if `mask_type->get_con_as_long(bt) == -1L`, then we can just return the type of `src`, right?
>
> This is a bug-fix for `CompressBitsNode::Value`, but this change also has an effect on `ExpandBitsNode::Value`, and that makes me a little nervous. For example: do we have enough test coverage for `expand`? It seems we did not have enough tests for `compress`, so probably also not for `expand`...
> Now you removed the condition `mask_type->get_con_as_long(bt) != -1L`. Do you know why it was there in the first place?
>
> It seems to me that if `mask_type->get_con_as_long(bt) == -1L`, then we can just return the type of `src`, right?
Correct, also for non-constant masks we can even find the maximum set bit count of entier value range and then estimate the bounds of the result.
#include <stdint.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
uint64_t popcnt(int64_t val) {
uint64_t res = 0;
asm volatile("popcntq %1, %0 " : "=r"(res) : "r"(val) : "cc");
return res;
}
typedef struct _result {
int64_t value;
int64_t mask;
int64_t count;
} result;
result compute_max_mask(int64_t hi, int64_t lo) {
assert(hi >= lo);
result res;
int64_t max_true_bits = 0;
int64_t max_true_bits_val = 0;
for (int64_t iter = lo; iter < hi; iter++) {
int setbitscnt = popcnt(iter);
if (max_true_bits < setbitscnt) {
max_true_bits = setbitscnt;
max_true_bits_val = iter;
}
}
res.value = max_true_bits_val;
res.mask = (1L << max_true_bits) - 1L;
res.count = max_true_bits;
return res;
}
int main(int argc, char* argv[]) {
if (argc != 3) {
return printf("Invalid arguments, <app> [lo] [hi]\n");
}
int64_t lo = atol(argv[1]);
int64_t hi = atol(argv[2]);
result mask = compute_max_mask(hi, lo);
return printf("[lo] = %ld [hi] = %ld [set bits count] %ld [mask] = %ld [max bits count value] %ld\n",
lo, hi, mask.count, mask.mask, mask.value);
}
For this bug fix patch I don't want to include this extension.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/23947#discussion_r2204754331
More information about the hotspot-compiler-dev
mailing list