RFR: 8315066: Add unsigned bounds and known bits to TypeInt/Long [v64]
Quan Anh Mai
qamai at openjdk.org
Tue Jun 10 15:53:54 UTC 2025
On Tue, 10 Jun 2025 07:46:46 GMT, Emanuel Peter <epeter at openjdk.org> wrote:
>>> @jatin-bhateja Thanks a lot for your suggestion. I will address your concerns below:
>>>
>>> In addition to being additional information, unsigned bounds make it easier for canonicalization. This is because bits are inherently unsigned, canonicalizing bits and unsigned bounds together is an easier task than canonicalize bits and signed bounds. I think it is also beneficial to be consistent, keeping a boolean to signify unsigned bounds splits the set of all `TypeInt`s into 2, which makes it hard to reason about and verify the results of different operations. For example, consider substracting 2 `TypeInt`s, it will be significantly more complex if we have to consider 4 cases: signed - signed, signed - unsigned, unsigned - signed, unsigned - unsigned.
>>>
>>> I don't think it suffices to think that Java integral types are inherently signed. Bitwise and, or, xor, not are inherently unsigned. Left shift is both signed and unsigned, right shift has both the signed variant and the unsigned variant. Add, sub, mul are both signed and unsigned. There are only cmp, div, mod, toString and conversions that are signed, but we have methods to do the unsigned variants for all of them, `Integer::compareUnsigned`, `Integer::divide/remainderUnsigned`, `Integer::toUnsignedString`, and `Integer::toUnsignedLong`. Mul-hi does not have a native operation for both variants and `j.l.Math` provides both the signed and unsigned variants as utility methods. As a result, I think it is better to think of and `int` as a 32-bit integral value with unspecified signness and the operations operated on it are what decide whether it is signed or unsigned. And as you can see, for all operations, we have both the signed and unsigned variants.
>>
>> "As a result, I think it is better to think of and `int` as a 32-bit integral value with unspecified signness and the operations operated on it are what decide whether it is signed or unsigned"
>>
>> Sounds good, I think since now integral types has multiple lattics point associated with it, and all our existing Value transforms are based on signed value ranges, we will also need to extend existing value transforms to make use of KnownBits, for that we will need to extend newly added KnownBits class to support other operations which accepts KnownBits inputs operates over them as per the operation semantics and returns a new [KnownBits](https://github.com/llvm/llvm-project/blob/0c3a7725375ec583147429cc367320f0e8506847/llvm/include/llvm/Support/KnownBits...
>
> So there is indeed a lot of extension work to do, like @jatin-bhateja said. But we can use that to also refactor the code for testability.
@eme64 I have created https://bugs.openjdk.org/browse/JDK-8359149
-------------
PR Comment: https://git.openjdk.org/jdk/pull/17508#issuecomment-2959794755
More information about the hotspot-compiler-dev
mailing list