RFR (XS): 8191915: JCK tests produce incorrect results with C2

Tobias Hartmann tobias.hartmann at oracle.com
Thu Dec 14 11:26:00 UTC 2017


On 14.12.2017 11:54, Rickard Bäckman wrote:
> Yes you are right, it doesn't work for all values. Seems to work for
> negatives though?

I think for negative values this does not work at all. If you set sv1 = -5 in my example code, you get:

-10
18446744073709551606
Overflow detected

Because we cast a negative value to unsigned.

> However casting the result back to signed after doing the multiplication
> and doing the division with the signed values get us back to getting the
> overflow check correct and no undefined behaviour as far as I can tell?

Yes, that seems to work. The best solution would be to use the corresponding compiler build-in functions (for example,
__builtin_smulll_overflow for gcc [1]) but I guess not all compilers support that.

Best regards,
Tobias

[1] https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html

> On 12/14, Tobias Hartmann wrote:
>> Hi Rickard,
>>
>> I don't understand why casting from signed to unsigned is correct here because if there's an overflow of the signed
>> range, there is not necessarily and overflow of the unsigned range, right?
>>
>> For example, this program:
>>
>>   signed long long sv1 = LONG_MAX/2 + 1;
>>   signed long long sv2 = 2;
>>   signed long long sR = sv1 * sv2;
>>   printf("%li\n", sR);
>>
>>   unsigned long long uv1 = (unsigned long long) sv1;	
>>   unsigned long long uv2 = (unsigned long long) sv2;
>>   unsigned long long uR = uv1 * uv2;
>>   printf("%lu\n", uR);
>>
>>   if (uR / uv1 != uv2) {
>>     printf("Overflow detected");
>>   } else {
>>     printf("No overflow detected");
>>   }
>>
>> Output:
>>
>>   -9223372036854775808
>>   9223372036854775808
>>   No overflow detected
>>
>> So there is an overflow of the signed long but the unsigned long does not overflow and thus an overflow is not detected.
>> Do I miss something?
>>
>> Regarding the jtreg test: Please do not use bug numbers as test names but use something more meaningful like
>> TestLongMulOverflow or similar. I would also suggest to move the allocation of the test instance out of the loop and
>> check if 500.000 iterations are really necessary to trigger compilation (you can run with -Xbatch and maybe
>> -XX:-TieredCompilation).
>>
>> Best regards,
>> Tobias
>>
>> On 14.12.2017 08:30, Rickard Bäckman wrote:
>>> Hi, can I please have this change reviewed?
>>>
>>> Summary is that we had an overflow check for mulitplyExact(long, long)
>>> intrinsic that relied on undefined behaviour. clang / llvm started
>>> optimizing that so that if a = b * c then a / b must be equal to c and
>>> removed half of the overflow check. 
>>>
>>> Changing the multiplication and division to be unsigned.
>>>
>>> Webrev: http://cr.openjdk.java.net/~rbackman/8191915/
>>> Bug: https://bugs.openjdk.java.net/browse/JDK-8191915
>>>
>>> Thanks
>>> /R
>>>


More information about the hotspot-compiler-dev mailing list