Division by INT64_MIN

2015-10-04 Thread Matthew Fernandez

Hello all,

Apologies in advance if this question is naïve or misdirected.

tl;dr: Is dividing by INT64_MIN in C undefined behaviour?

In more detail... AIUI when the current target does not have native instructions for a given division or modulo 
operation, GCC emits calls to software emulation provided by libgcc. For example, a signed 64-bit division on x86 is 
emitted as a call to __divdi3. If the numerator or denominator are negative, __divdi3 negates them. If either of these 
values is INT64_MIN, I believe this negation is undefined. Is this correct? If this is the case, then it seems code like 
"INT64_MIN / INT64_MIN" which should be perfectly legal accidentally causes undefined behaviour via libgcc. In practice, 
everything seems to work as expected, but it seems to me that the C code of __divdi3 should not be relying on these 
negations working consistently.


This only occurred to me after being in a situation where I had to implement __divdi3 myself. Afterwards I looked at 
libgcc's out of curiosity and was surprised to find it was much simpler than my attempt. Any clarification would be 
appreciated.


Thanks,
Matthew


Re: Division by INT64_MIN

2015-10-07 Thread Matthew Fernandez

On 06/10/15 01:09, Joseph Myers wrote:

On Mon, 5 Oct 2015, Matthew Fernandez wrote:


on x86 is emitted as a call to __divdi3. If the numerator or denominator are
negative, __divdi3 negates them. If either of these values is INT64_MIN, I
believe this negation is undefined. Is this correct? If this is the case, then
it seems code like "INT64_MIN / INT64_MIN" which should be perfectly legal
accidentally causes undefined behaviour via libgcc. In practice, everything
seems to work as expected, but it seems to me that the C code of __divdi3
should not be relying on these negations working consistently.


It sounds like some casts to UDWtype should be inserted so the negation
takes place on an unsigned type.


Thanks for the speedy response, Joseph. Should I open a new bug report about this? I suspect there 
are GCC developers out there who would disagree that this constitutes a bug.


Re: Division by INT64_MIN

2015-10-08 Thread Matthew Fernandez

On 09/10/15 02:08, Joseph Myers wrote:

On Thu, 8 Oct 2015, Matthew Fernandez wrote:


On 06/10/15 01:09, Joseph Myers wrote:

On Mon, 5 Oct 2015, Matthew Fernandez wrote:


on x86 is emitted as a call to __divdi3. If the numerator or denominator
are
negative, __divdi3 negates them. If either of these values is INT64_MIN, I
believe this negation is undefined. Is this correct? If this is the case,
then
it seems code like "INT64_MIN / INT64_MIN" which should be perfectly legal
accidentally causes undefined behaviour via libgcc. In practice,
everything
seems to work as expected, but it seems to me that the C code of __divdi3
should not be relying on these negations working consistently.


It sounds like some casts to UDWtype should be inserted so the negation
takes place on an unsigned type.


Thanks for the speedy response, Joseph. Should I open a new bug report about
this? I suspect there are GCC developers out there who would disagree that
this constitutes a bug.


If you don't intend to send a patch, I suggest opening a bug report (but I
expect it's a bug only in the source code, not in the libgcc binaries).


OK, created as https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67902.

In my own implementation I just special cased all the tricky pairs of operands, which worked fine as I'm not doing any 
64-bit divisions in performance-critical sections. However, I'm hesitant to submit something like this as a patch 
because I suspect the performance degradation would be unpalatable to others.