https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67902

            Bug ID: 67902
           Summary: Undefined negation in __divdi3
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libgcc
          Assignee: unassigned at gcc dot gnu.org
          Reporter: matthew.fernandez at gmail dot com
                CC: joseph at codesourcery dot com
  Target Milestone: ---

As discussed on the GCC list, I believe the function __divdi3 performs a signed
negation that may be undefined behaviour.

In more detail: AIUI, signed 64-bit division can be emitted as a call to
software emulation in libgcc when the current target has no native hardware
support. For example, on 32-bit x86 this can mean signed 64-bit division
becomes a call to __divdi3. Internally, this function negates its operands if
they are negative. I believe this negation, in the case when either of the
operands is INT64_MIN is undefined behaviour. This seems to mean that a legal
operation like `INT64_MIN / INT64_MIN` inadvertently causes undefined
behaviour. Thus I believe __divdi3's implementation doesn't strictly comply
with the C standard.

There may be some disagreement about this as presumably GCC does the expected
thing when compiling this code and, as Joseph Myers has pointed out, the
shipped libgcc binaries are probably fine. However, I believe a compiler is
within its rights to transform `x = -x` into:

if (x == INT64_MIN) {
  // nasal demons
} else {
  x = -x;
}

Please let me know if I'm mistaken or if you need more information. If I'm
incorrect, apologies for taking up your time.

GCC commit: 03ca0c3cbd35930b7e08135e5f2ac069db22f7f7

Reply via email to