This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/40579] New: gcc -O2 optimization causes infinite loop and wrong output


$ gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: /root/gcc-4.4.0/configure --prefix=/opt/gcc-4.4.0
--enable-languages=c,c++
Thread model: posix
gcc version 4.4.0 (GCC)

Here is a program to reproduce this problem :-

#include <stdio.h>
#include <string.h>

#define MinWordStr "-2147483648"
#define MinWord  ((long)0x80000000)   /* smallest word */

/* Simple function to convert long to a string */
static char * itos(long num)
{
    char *p;
    static char buff[64];

    p = buff + sizeof(buff) - 1;

    *p = '\0';
    if (num >= 0L)
        do {
            *--p = num % 10L + '0';
            num /= 10L;
        } while (num != 0L);
    else {
        if (num == MinWord) {      /* max negative value */
            p -= strlen (MinWordStr);
            strcpy (p, MinWordStr);
        }
        else {
            num = -num;
            do {
                *--p = '0' + (num % 10L);
                num /= 10L;
            } while (num != 0L);
            *--p = '-';
        }
    }

    return p;
}

int main() {
    char *p;
    long x = -2147483645;
    int i;

    for (i = 0; i < 4; ++i) {
        p = itos(x);
        printf("i=%d p=%s\n",i,p);
        --x;
    }

    return 0;
}


When run with -O1 it runs okay.

$ gcc -O1 prog.c && ./a.out
i=0 p=-2147483645
i=1 p=-2147483646
i=2 p=-2147483647
i=3 p=-2147483648

But with -O2 it goes haywire.
$ gcc -O2 progg.c && ./a.out
i=0 p=-2147483645
i=1 p=-2147483646
i=2 p=-2147483647
i=3 p=-2147483648
i=4 p=-./,),(-*,)
i=5 p=-./,),(-*,*
i=6 p=-./,),(-*,+
i=7 p=-./,),(-*,,
...etc ad infinitum

Note that if the line
        if (num == MinWord) {      /* max negative value */
is changed to
        if (num == -num) {      /* max negative value */

a different (and also incorrect) result occurs with -O2
$ gcc -O2 prog.c && ./a.out
i=0 p=-2147483645
i=1 p=-2147483646
i=2 p=-2147483647
i=3 p=-./,),(-*,(

Other points:
1) this has something to do with the value of x reaching the most negative
32-bit long (ie: -2147483648, or 0x80000000) - if it stays away from that by
initializing x = -2147483644 instead of -2147483645 it is okay.
2) gcc 2.95.3 seems to work okay with -O2


-- 
           Summary: gcc -O2 optimization causes infinite loop and wrong
                    output
           Product: gcc
           Version: 4.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: dentongosnell at yahoo dot com
 GCC build triplet: i686-pc-linux
  GCC host triplet: i686-pc-linux
GCC target triplet: i686-pc-linux


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40579


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]