Skip to content

Commit b02c125

Browse files
Jatin Bhatejaeme64
andcommitted
8350896: Integer/Long.compress gets wrong type from CompressBitsNode::Value
Co-authored-by: Emanuel Peter <[email protected]> Reviewed-by: thartmann
1 parent 06f9ff0 commit b02c125

File tree

3 files changed

+833
-37
lines changed

3 files changed

+833
-37
lines changed

src/hotspot/share/opto/intrinsicnode.cpp

Lines changed: 156 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -237,58 +237,167 @@ static const Type* bitshuffle_value(const TypeInteger* src_type, const TypeInteg
237237

238238
jlong hi = bt == T_INT ? max_jint : max_jlong;
239239
jlong lo = bt == T_INT ? min_jint : min_jlong;
240+
assert(bt == T_INT || bt == T_LONG, "");
240241

241-
if(mask_type->is_con() && mask_type->get_con_as_long(bt) != -1L) {
242+
// Rule 1: Bit compression selects the source bits corresponding to true mask bits,
243+
// packs them and places them contiguously at destination bit positions
244+
// starting from least significant bit, remaining higher order bits are set
245+
// to zero.
246+
247+
// Rule 2: Bit expansion is a reverse process, which sequentially reads source bits
248+
// starting from LSB and places them at bit positions in result value where
249+
// corresponding mask bits are 1. Thus, bit expansion for non-negative mask
250+
// value will always generate a +ve value, this is because sign bit of result
251+
// will never be set to 1 as corresponding mask bit is always 0.
252+
253+
// Case A) Constant mask
254+
if (mask_type->is_con()) {
242255
jlong maskcon = mask_type->get_con_as_long(bt);
243-
int bitcount = population_count(static_cast<julong>(bt == T_INT ? maskcon & 0xFFFFFFFFL : maskcon));
244256
if (opc == Op_CompressBits) {
245-
// Bit compression selects the source bits corresponding to true mask bits
246-
// and lays them out contiguously at destination bit positions starting from
247-
// LSB, remaining higher order bits are set to zero.
248-
// Thus, it will always generate a +ve value i.e. sign bit set to 0 if
249-
// any bit of constant mask value is zero.
250-
lo = 0L;
251-
hi = (1UL << bitcount) - 1;
257+
// Case A.1 bit compression:-
258+
// For an outlier mask value of -1 upper bound of the result equals
259+
// maximum integral value, for any other mask value its computed using
260+
// following formula
261+
// Result.Hi = 1 << popcount(mask_bits) - 1
262+
//
263+
// For mask values other than -1, lower bound of the result is estimated
264+
// as zero, by assuming at least one mask bit is zero and corresponding source
265+
// bit will be masked, hence result of bit compression will always be
266+
// non-negative value. For outlier mask value of -1, assume all source bits
267+
// apart from most significant bit were set to 0, thereby resulting in
268+
// a minimum integral value.
269+
// e.g.
270+
// src = 0xXXXXXXXX (non-constant source)
271+
// mask = 0xEFFFFFFF (constant mask)
272+
// result.hi = 0x7FFFFFFF
273+
// result.lo = 0
274+
if (maskcon != -1L) {
275+
int bitcount = population_count(static_cast<julong>(bt == T_INT ? maskcon & 0xFFFFFFFFL : maskcon));
276+
hi = (1UL << bitcount) - 1;
277+
lo = 0L;
278+
} else {
279+
// preserve originally assigned hi (MAX_INT/LONG) and lo (MIN_INT/LONG) values
280+
// for unknown source bits.
281+
assert(hi == (bt == T_INT ? max_jint : max_jlong), "");
282+
assert(lo == (bt == T_INT ? min_jint : min_jlong), "");
283+
}
252284
} else {
285+
// Case A.2 bit expansion:-
253286
assert(opc == Op_ExpandBits, "");
254-
// Expansion sequentially reads source bits starting from LSB
255-
// and places them over destination at bit positions corresponding
256-
// set mask bit. Thus bit expansion for non-negative mask value
257-
// will always generate a +ve value.
258-
hi = maskcon >= 0L ? maskcon : maskcon ^ lo;
259-
lo = maskcon >= 0L ? 0L : lo;
287+
if (maskcon >= 0L) {
288+
// Case A.2.1 constant mask >= 0
289+
// Result.Hi = mask, optimistically assuming all source bits
290+
// read starting from least significant bit positions are 1.
291+
// Result.Lo = 0, because at least one bit in mask is zero.
292+
// e.g.
293+
// src = 0xXXXXXXXX (non-constant source)
294+
// mask = 0x7FFFFFFF (constant mask >= 0)
295+
// result.hi = 0x7FFFFFFF
296+
// result.lo = 0
297+
hi = maskcon;
298+
lo = 0L;
299+
} else {
300+
// Case A.2.2) mask < 0
301+
// For constant mask strictly less than zero, the maximum result value will be
302+
// the same as the mask value with its sign bit flipped, assuming all source bits
303+
// except the MSB bit are set(one).
304+
//
305+
// To compute minimum result value we assume all but last read source bit as zero,
306+
// this is because sign bit of result will always be set to 1 while other bit
307+
// corresponding to set mask bit should be zero.
308+
// e.g.
309+
// src = 0xXXXXXXXX (non-constant source)
310+
// mask = 0xEFFFFFFF (constant mask)
311+
// result.hi = 0xEFFFFFFF ^ 0x80000000 = 0x6FFFFFFF
312+
// result.lo = 0x80000000
313+
//
314+
hi = maskcon ^ lo;
315+
// lo still retains MIN_INT/LONG.
316+
assert(lo == (bt == T_INT ? min_jint : min_jlong), "");
317+
}
260318
}
261319
}
262320

321+
// Case B) Non-constant mask.
263322
if (!mask_type->is_con()) {
264-
int mask_max_bw;
265-
int max_bw = bt == T_INT ? 32 : 64;
266-
// Case 1) Mask value range includes -1.
267-
if ((mask_type->lo_as_long() < 0L && mask_type->hi_as_long() >= -1L)) {
268-
mask_max_bw = max_bw;
269-
// Case 2) Mask value range is less than -1.
270-
} else if (mask_type->hi_as_long() < -1L) {
271-
mask_max_bw = max_bw - 1;
272-
} else {
273-
// Case 3) Mask value range only includes +ve values.
274-
assert(mask_type->lo_as_long() >= 0, "");
275-
jlong clz = count_leading_zeros(mask_type->hi_as_long());
276-
clz = bt == T_INT ? clz - 32 : clz;
277-
mask_max_bw = max_bw - clz;
278-
}
279323
if ( opc == Op_CompressBits) {
280-
lo = mask_max_bw == max_bw ? lo : 0L;
281-
// Compress operation is inherently an unsigned operation and
282-
// result value range is primarily dependent on true count
283-
// of participating mask value.
284-
hi = mask_max_bw < max_bw ? (1L << mask_max_bw) - 1 : src_type->hi_as_long();
324+
int result_bit_width;
325+
int mask_bit_width = bt == T_INT ? 32 : 64;
326+
if ((mask_type->lo_as_long() < 0L && mask_type->hi_as_long() >= -1L)) {
327+
// Case B.1 The mask value range includes -1, hence we may use all bits,
328+
// the result has the whole value range.
329+
result_bit_width = mask_bit_width;
330+
} else if (mask_type->hi_as_long() < -1L) {
331+
// Case B.2 Mask value range is strictly less than -1, this indicates presence of at least
332+
// one unset(zero) bit in mask value, thus as per Rule 1, bit compression will always
333+
// result in a non-negative value. This guarantees that MSB bit of result value will
334+
// always be set to zero.
335+
result_bit_width = mask_bit_width - 1;
336+
} else {
337+
assert(mask_type->lo_as_long() >= 0, "");
338+
// Case B.3 Mask value range only includes non-negative values. Since all integral
339+
// types honours an invariant that TypeInteger._lo <= TypeInteger._hi, thus computing
340+
// leading zero bits of upper bound of mask value will allow us to ascertain
341+
// optimistic upper bound of result i.e. all the bits other than leading zero bits
342+
// can be assumed holding 1 value.
343+
jlong clz = count_leading_zeros(mask_type->hi_as_long());
344+
// Here, result of clz is w.r.t to long argument, hence for integer argument
345+
// we explicitly subtract 32 from the result.
346+
clz = bt == T_INT ? clz - 32 : clz;
347+
result_bit_width = mask_bit_width - clz;
348+
}
349+
// If the number of bits required to for the mask value range is less than the
350+
// full bit width of the integral type, then the MSB bit is guaranteed to be zero,
351+
// thus the compression result will never be a -ve value and we can safely set the
352+
// lower bound of the bit compression to zero.
353+
lo = result_bit_width == mask_bit_width ? lo : 0L;
354+
355+
assert(hi == (bt == T_INT ? max_jint : max_jlong), "");
356+
assert(lo == (bt == T_INT ? min_jint : min_jlong) || lo == 0, "");
357+
358+
if (src_type->lo_as_long() >= 0) {
359+
// Lemma 1: For strictly non-negative src, the result of the compression will never be
360+
// greater than src.
361+
// Proof: Since src is a non-negative value, its most significant bit is always 0.
362+
// Thus even if the corresponding MSB of the mask is one, the result will be a +ve
363+
// value. There are three possible cases
364+
// a. All the mask bits corresponding to set source bits are unset(zero).
365+
// b. All the mask bits corresponding to set source bits are set(one)
366+
// c. Some mask bits corresponding to set source bits are set(one) while others are unset(zero)
367+
//
368+
// Case a. results into an allzero result, while Case b. gives us the upper bound which is equals source
369+
// value, while for Case c. the result will lie within [0, src]
370+
//
371+
hi = src_type->hi_as_long();
372+
lo = 0L;
373+
}
374+
375+
if (result_bit_width < mask_bit_width) {
376+
// Rule 3:
377+
// We can further constrain the upper bound of bit compression if the number of bits
378+
// which can be set(one) is less than the maximum number of bits of integral type.
379+
hi = MIN2((jlong)((1UL << result_bit_width) - 1L), hi);
380+
}
285381
} else {
286382
assert(opc == Op_ExpandBits, "");
287383
jlong max_mask = mask_type->hi_as_long();
384+
jlong min_mask = mask_type->lo_as_long();
288385
// Since mask here a range and not a constant value, hence being
289386
// conservative in determining the value range of result.
290-
lo = mask_type->lo_as_long() >= 0L ? 0L : lo;
291-
hi = mask_type->lo_as_long() >= 0L ? max_mask : hi;
387+
if (min_mask >= 0L) {
388+
// Lemma 2: Based on the integral type invariant ie. TypeInteger.lo <= TypeInteger.hi,
389+
// if the lower bound of non-constant mask is a non-negative value then result can never
390+
// be greater than the mask.
391+
// Proof: Since lower bound of the mask is a non-negative value, hence most significant
392+
// bit of its entire value must be unset(zero). If all the lower order 'n' source bits
393+
// where n corresponds to popcount of mask are set(ones) then upper bound of the result equals
394+
// mask. In order to compute the lower bound, we pssimistically assume all the lower order 'n'
395+
// source bits are unset(zero) there by resuling into a zero value.
396+
hi = max_mask;
397+
lo = 0;
398+
} else {
399+
// preserve the lo and hi bounds estimated till now.
400+
}
292401
}
293402
}
294403

@@ -329,6 +438,11 @@ const Type* CompressBitsNode::Value(PhaseGVN* phase) const {
329438
static_cast<const Type*>(TypeLong::make(res));
330439
}
331440

441+
// Result is zero if src is zero irrespective of mask value.
442+
if (src_type == TypeInteger::zero(bt)) {
443+
return TypeInteger::zero(bt);
444+
}
445+
332446
return bitshuffle_value(src_type, mask_type, Op_CompressBits, bt);
333447
}
334448

@@ -365,5 +479,10 @@ const Type* ExpandBitsNode::Value(PhaseGVN* phase) const {
365479
static_cast<const Type*>(TypeLong::make(res));
366480
}
367481

482+
// Result is zero if src is zero irrespective of mask value.
483+
if (src_type == TypeInteger::zero(bt)) {
484+
return TypeInteger::zero(bt);
485+
}
486+
368487
return bitshuffle_value(src_type, mask_type, Op_ExpandBits, bt);
369488
}

0 commit comments

Comments
 (0)