Search code examples
x86undefined-behaviorsignedinteger-overflow

Is INT_MIN * -1 a no-op on x86?


Signed integers are represented on x86 via two's complement, where the sign bit has the value -(2^N). This results in a typical representable value range between -2^N and 2^N - 1 (e.g. -32768 through 32767).

I was curious what would occur if I took the minimum signed integer value on my system and multiply it by -1 in an attempt to "force" a maximum value greater than the maximum representable value of signed integers on my system.

#include <stdio.h>
#include <limits.h>

int main(void){
    signed int x, y;

    x = INT_MIN;
    y = x * -1;

    printf("%d\n%d\n", x, y);

    return 0;
}

This resulted in the following output:

# gcc -std=c89 -pedantic int_min_test.c

# ./a.out
-2147483648
-2147483648

I was expecting an integer overflow (resulting in the typical value rollover), but it appears as if no operation took place regarding the multiplication of x with -1.

Is the multiplication of INT_MIN with -1 a no-op in x86?


Solution

  • Using gcc 4.8.5, the line y = x * -1; is computed using the following instruction:

    neg    %eax
    

    The neg operation flips the bits of the word and then adds 1. For 32 bit 2's complement the result is:

    0x80000000 # Start value
    0x7FFFFFFF # Flip bits
    0x80000000 # Add 1
    

    As you see, the computer is doing exactly what you are telling it to do. This is not a no-op, as neg modifies the AF, CF, OF, PF, SF, and ZF flags. It is just an artifact of the binary representation being used. As others have stated it is simply undefined behavior.