[aarch64] assert(is_power_of_2(x)) failed: x must be a power of 2: 0xffffffff80000000
Stuart Monteith
stuart.monteith at arm.com
Thu Feb 27 14:39:49 UTC 2020
The majority of the uses of "exact_log2" aren't concerned so with
arithmetic as such, but bit manipulation. In other words it is being
used to get the number of the most-significant bit. Likewise,
is_power_of_2 is being used in much the same way.
Would it be appropriate to have two sets of functions for these quite
distinct purposes? "exact_log2" is being used for the number of the most
significant bit, and is_power_of_2 is being used to test is only one bit
is set.
Stuart
On 26/02/2020 14:30, Andrew Haley wrote:
> On 2/25/20 7:01 PM, Doerr, Martin wrote:
>>
>>> These overflow when x is the largest negative integer. This is
>>> Undefined Behaviour, so we have to fix it somehow.
>>
>> That's right.
>>
>>> We'd do much better converting to an unsigned type and then
>>> performing the calculation on that. Maybe we should provide just
>>> one definition of this function, casting its argument to uint64_t.
>>
>> I agree. We should never use is_power_of_2 or exact_log2 with signed types.
>
> The trouble with this reasoning is that jint has both the behaviour of
> signed and unsigned types in C++. On the one hand, jints can be
> interpreted as signed, but on the other hand the +/-/* and bitwise
> operations on Java's ints behave like C++ unsigned types.
>
> We could make it so that is_power_of_2 failed to compile if passed a
> signed type. However, existing practice in HotSpot is that all of the
> log2 functions cast signed types to unsigned types, for example:
>
> inline int log2_int(int x) {
> STATIC_ASSERT(sizeof(int) <= sizeof(uintptr_t));
> return log2_intptr((uintptr_t)x);
> }
>
> inline int log2_jint(jint x) {
> STATIC_ASSERT(sizeof(jint) <= sizeof(uintptr_t));
> return log2_intptr((uintptr_t)x);
> }
>
> Therefore, I believe that it would be appropriate to follow existing
> practice in is_power_of_2, like so:
>
> template <typename T>
> bool is_power_of_2(T val) {
> STATIC_ASSERT(sizeof(T) <= sizeof(julong));
> julong x = val;
> return (x != 0) && ((x & (x - 1)) == 0);
> }
>
> // Log2 of a power of 2
> template <typename T>
> inline int exact_log2(T val) {
> STATIC_ASSERT(sizeof(T) <= sizeof(julong));
> julong x = val;
> assert(is_power_of_2(x), "x must be a power of 2: " JULONG_FORMAT, x);
> return log2_long(x);
> }
>
More information about the hotspot-compiler-dev
mailing list