public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug middle-end/34300]  New: gcc 4.2.2 miscompiles code that uses global register variables
@ 2007-11-30 10:45 bruno at clisp dot org
  2007-11-30 10:47 ` [Bug middle-end/34300] " bruno at clisp dot org
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: bruno at clisp dot org @ 2007-11-30 10:45 UTC (permalink / raw)
  To: gcc-bugs

$ gcc -v
Using built-in specs.
Target: i686-pc-linux-gnu
Configured with: ../gcc-4.2.2/configure --prefix=/packages/gnu-inst-gcc/4.2.2
--enable-shared --enable-version-specific-runtime-libs --enable-nls
--enable-threads=posix --enable-__cxa_atexit --with-as=/packages/gnu/bin/as
--with-ld=/packages/gnu/bin/ld --with-gmp=/packages/gnu-inst-gcc/4.2.2
--with-mpfr=/packages/gnu-inst-gcc/4.2.2
--with-ecj-jar=/gfs/ibook/Volumes/ExtData/source/gnu/gcc/sourceware.org-ecj/ecj-latest.jar
Thread model: posix
gcc version 4.2.2
$ gcc bug.c
$ ./a.out ; echo $?
0
$ gcc -O bug.c
$ ./a.out ; echo $?
Aborted
134

================================= bug.c ====================================
typedef unsigned char UBYTE;
typedef long SLONG;
typedef unsigned long ULONG;
typedef ULONG uint32;
typedef SLONG sint32;
typedef sint32 sintL;
typedef uint32 uintL;
typedef sint32 sintP;
typedef uint32 uintP;
typedef void * gcv_object_t;
typedef uintP oint;
typedef uint32 tint;
typedef uint32 aint;
typedef uint32 uintV;
typedef gcv_object_t object;
typedef struct {
  gcv_object_t cdr ;
  gcv_object_t car ;
} cons_;
typedef cons_ * Cons;
typedef struct {
  gcv_object_t GCself;
} symbol_;
typedef symbol_ * Symbol;
typedef struct {
  gcv_object_t GCself;
  gcv_object_t data[2] ;
} svector_;
typedef svector_ * Svector;
register gcv_object_t* STACK __asm__("%ebx");
extern object allocate_vector (uintL len);
struct symbol_tab_ {
  symbol_ S_nil;
} symbol_tab_data = { { (UBYTE*)&symbol_tab_data.S_nil+2 } };
extern void newinsert (object sym, uintL size);
extern void abort (void);
static gcv_object_t stackspace[100];
object rehash_symtab (object symtab)
{
  STACK[0] = symtab, STACK += 1;
  {
    uintL oldsize =
((uintV)(((oint)((((Svector)((oint)(symtab)-2))->data[0]))&((oint)0x20000000UL-1))>>5));
    {
      uintL newsize;
      {
        object size;
        STACK[0] = ((Svector)((oint)(symtab)-2))->data[1], STACK += 1;
        STACK[0] = (object)((UBYTE*)(&symbol_tab_data.S_nil)+2), STACK += 1;
        {
          uint32 prod = oldsize * 205UL;
          newsize = (prod < (1UL<<31) ? prod>>7 : 0xffffffUL);
        }
        newsize = (newsize - 1) | 1 ;
        size = ((gcv_object_t)((oint)(tint)0xC0000000 + ((oint)(aint)(newsize)
<< 5)));
        {
          object newtable = allocate_vector(newsize);
          STACK[0] = newtable, STACK += 1;
        }
        {
          gcv_object_t* offset = 0;
          uintL count;
          count = oldsize;
          do
            {
              object oldentry =
*(gcv_object_t*)(((UBYTE*)(&((Svector)((oint)(((STACK[-3])))-2))->data[0])+((aint)offset)));
              if (((oint)(oldentry) & 3) == 2)
                do
                  {
                    STACK[0] = ((Cons)((oint)(oldentry)-2))->cdr, STACK += 1;
                    ((Cons)((oint)(oldentry)-2))->cdr = STACK[-3];
                    STACK[-3] = oldentry;
                    newinsert(((Cons)((oint)(oldentry)-2))->car,newsize);
                    oldentry = (STACK -= 1, STACK[0]);
                  }
                while (((oint)(oldentry) & 3) == 2);
              offset++;
            }
          while(!(--count==0));
        }
        if (STACK != &stackspace[54])
          abort();
        {
          object newtable = (STACK -= 1, STACK[0]);
          STACK -= 2;
          symtab = (STACK -= 1, STACK[0]);
          ((Svector)((oint)(symtab)-2))->data[0] = size;
          ((Svector)((oint)(symtab)-2))->data[1] = newtable;
        }
        return symtab;
      }
    }
  }
}
object allocate_vector (uintL len)
{
  return 0;
}
void newinsert (object sym, uintL size)
{
  if (STACK != &stackspace[55])
    abort();
}
static cons_ cons2 = { (void*)0, (void*)'2' };
static cons_ cons1 = { (UBYTE*)&cons2+2, (void*)'1' };
static svector_ vector1 = { (UBYTE*)&vector1+2, { (UBYTE*)&cons1+2, 0 } };
static svector_ symtab1 = { (UBYTE*)&symtab1+2, { (void*)0x20000020,
(UBYTE*)&vector1+2 } };
int main ()
{
  STACK = &stackspace[50];
  rehash_symtab((UBYTE*)&symtab1+2);
  return 0;
}
============================================================================

This is a regression, because gcc 3.4.4, gcc 4.0.4, and gcc 4.1.2 all compile
this program fine, even with higher optimization levels (-O2).

What happens is that gcc 4.2.2 keeps a "cache" of the STACK = %ebx variable
in another register, %edi, in the inner loop, around the function call of
newinsert(). Two things are wrong here:
1) It is wrong to assume that newinsert() will leave STACK unmodified.
   newinsert() could also always decrement STACK by 2, for example. You can
   see that the code is unchanged if the newinsert() function is put into a
   different compilation unit.
2) The value cached in %edi and used for this statement
     oldentry = (STACK -= 1, STACK[0]);
   is the value of STACK at the beginning of the loop MINUS 1.
   If assuming that newinsert() does not change the STACK, the value cached
   in %edi should be the value of STACK at the beginning of the loop
   (since there is one increment of STACK before the newinsert call and
   one decrement of STACK after it.

Here's an annotated listing of the rehash_symtab function produced:
========================== gcc -O -S bug.c ================================
...
rehash_symtab:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %edi
        pushl   %esi
        subl    $16, %esp
        movl    8(%ebp), %eax                   ; %eax := symtab
        movl    %eax, (%ebx)                    ; STACK[0] = symtab
        leal    4(%ebx), %ecx                   ; STACK += 1
        subl    $2, %eax
        movl    4(%eax), %edx
        andl    $536870911, %edx
        movl    %edx, %edi
        shrl    $5, %edi                        ; %edi := oldsize
        movl    8(%eax), %eax                   ; Get
((Svector)((oint)(symtab)-2))->data[1]
        movl    %eax, (%ecx)                    ; STACK[0] = ...
        addl    $4, %ecx                        ; STACK += 1
        movl    $symbol_tab_data+2, (%ecx)      ; STACK[0] =
(object)((UBYTE*)(&symbol_tab_data.S_nil)+2)
        leal    4(%ecx), %esi                   ; STACK += 1
        movl    %esi, %ebx
        imull   $205, %edi, %edx                ; prod = oldsize * 205UL
        movl    $16777215, %eax
        testl   %edx, %edx
        js      .L10
        movl    %edx, %eax
        shrl    $7, %eax
.L10:                                           ; newsize in %eax
        subl    $1, %eax
        orl     $1, %eax                        ; newsize = (newsize - 1) | 1
        movl    %eax, -12(%ebp)
        movl    %eax, (%esp)
        call    allocate_vector                 ; newtable =
allocate_vector(newsize)
        movl    %eax, (%esi)                    ; STACK[0] = newtable
        addl    $4, %ebx                        ; STACK += 1
        movl    %edi, %esi
        movl    $0, -16(%ebp)                   ; offset = 0
.L11:
        movl    -12(%ebx), %eax
        movl    -16(%ebp), %ecx
        movl    2(%ecx,%eax), %edx              ; %edx := oldentry
        movl    %edx, %eax
        andl    $3, %eax
        cmpl    $2, %eax
        jne     .L12                            ; (((oint)(oldentry) & 3) == 2)
        leal    -4(%ebx), %edi                  ; HERE! %edi := STACK - 1
.L19:                                           ; BEGINNING OF INNER LOOP
        movl    -2(%edx), %eax
        movl    %eax, (%ebx)                    ; STACK[0] =
((Cons)((oint)(oldentry)-2))->cdr
        leal    4(%ebx), %eax
        movl    %eax, %ebx                      ; STACK += 1
        movl    -12(%eax), %eax
        movl    %eax, -2(%edx)                  ;
((Cons)((oint)(oldentry)-2))->cdr = STACK[-3]
        movl    %edx, -12(%ebx)                 ; STACK[-3] = oldentry
        movl    -12(%ebp), %eax                 ; newsize
        movl    %eax, 4(%esp)
        movl    2(%edx), %eax
        movl    %eax, (%esp)
        call    newinsert                       ;
newinsert(((Cons)((oint)(oldentry)-2))->car,newsize)
        movl    %edi, %ebx                      ; HERE! BUG! WRONG VALUE FOR
STACK!
        movl    (%edi), %edx                    ; oldentry = STACK[0]
        movl    %edx, %eax
        andl    $3, %eax
        cmpl    $2, %eax
        je      .L19                            ; (((oint)(oldentry) & 3) == 2)
.L12:                                           ; END OF INNER LOOP
        subl    $1, %esi
        je      .L14                            ; while(!(--count==0))
        addl    $4, -16(%ebp)                   ; offset++
        jmp     .L11
.L14:
        cmpl    $stackspace+216, %ebx           ; (STACK != &stackspace[54])
        .p2align 4,,2
        je      .L16
        call    abort
.L16:
        movl    stackspace+212, %esi
        movl    $stackspace+200, %ebx
        movl    stackspace+200, %eax
        leal    -2(%eax), %ecx
        movl    -12(%ebp), %edx
        sall    $5, %edx
        subl    $1073741824, %edx               ; %edx := size
        movl    %edx, 4(%ecx)
        movl    %esi, 8(%ecx)
        addl    $16, %esp
        popl    %esi
        popl    %edi
        popl    %ebp
        ret
...
============================================================================


-- 
           Summary: gcc 4.2.2 miscompiles code that uses global register
                    variables
           Product: gcc
           Version: 4.2.2
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: middle-end
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: bruno at clisp dot org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/34300] gcc 4.2.2 miscompiles code that uses global register variables
  2007-11-30 10:45 [Bug middle-end/34300] New: gcc 4.2.2 miscompiles code that uses global register variables bruno at clisp dot org
@ 2007-11-30 10:47 ` bruno at clisp dot org
  2007-11-30 10:50 ` pinskia at gcc dot gnu dot org
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: bruno at clisp dot org @ 2007-11-30 10:47 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from bruno at clisp dot org  2007-11-30 10:46 -------
Created an attachment (id=14671)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14671&action=view)
source code exhibiting the bug


-- 


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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/34300] gcc 4.2.2 miscompiles code that uses global register variables
  2007-11-30 10:45 [Bug middle-end/34300] New: gcc 4.2.2 miscompiles code that uses global register variables bruno at clisp dot org
  2007-11-30 10:47 ` [Bug middle-end/34300] " bruno at clisp dot org
@ 2007-11-30 10:50 ` pinskia at gcc dot gnu dot org
  2007-11-30 11:10 ` rguenth at gcc dot gnu dot org
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-11-30 10:50 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from pinskia at gcc dot gnu dot org  2007-11-30 10:50 -------
hmm, i see some alias issues.


-- 


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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/34300] gcc 4.2.2 miscompiles code that uses global register variables
  2007-11-30 10:45 [Bug middle-end/34300] New: gcc 4.2.2 miscompiles code that uses global register variables bruno at clisp dot org
  2007-11-30 10:47 ` [Bug middle-end/34300] " bruno at clisp dot org
  2007-11-30 10:50 ` pinskia at gcc dot gnu dot org
@ 2007-11-30 11:10 ` rguenth at gcc dot gnu dot org
  2007-11-30 11:56 ` ismail at pardus dot org dot tr
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: rguenth at gcc dot gnu dot org @ 2007-11-30 11:10 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from rguenth at gcc dot gnu dot org  2007-11-30 11:09 -------
Works with trunk as well.  (Aliasing should be not the issue here,
strict-aliasing
is off)


-- 

rguenth at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
      Known to fail|                            |4.2.2
      Known to work|                            |4.1.2 4.3.0


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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/34300] gcc 4.2.2 miscompiles code that uses global register variables
  2007-11-30 10:45 [Bug middle-end/34300] New: gcc 4.2.2 miscompiles code that uses global register variables bruno at clisp dot org
                   ` (2 preceding siblings ...)
  2007-11-30 11:10 ` rguenth at gcc dot gnu dot org
@ 2007-11-30 11:56 ` ismail at pardus dot org dot tr
  2007-11-30 12:00 ` ismail at pardus dot org dot tr
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: ismail at pardus dot org dot tr @ 2007-11-30 11:56 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from ismail at pardus dot org dot tr  2007-11-30 11:56 -------
Are we sure it works with trunk? Because this is initially found as a clisp
crash bug and it still crashes with gcc 4.3 trunk but only when compiled with
-O2.


-- 


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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/34300] gcc 4.2.2 miscompiles code that uses global register variables
  2007-11-30 10:45 [Bug middle-end/34300] New: gcc 4.2.2 miscompiles code that uses global register variables bruno at clisp dot org
                   ` (3 preceding siblings ...)
  2007-11-30 11:56 ` ismail at pardus dot org dot tr
@ 2007-11-30 12:00 ` ismail at pardus dot org dot tr
  2007-12-26 14:31 ` pinskia at gcc dot gnu dot org
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: ismail at pardus dot org dot tr @ 2007-11-30 12:00 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from ismail at pardus dot org dot tr  2007-11-30 11:59 -------
Indeed testcase doesn't abort with gcc 4.3 20071130 , so there must be another
gcc bug hiding there :(


-- 


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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/34300] gcc 4.2.2 miscompiles code that uses global register variables
  2007-11-30 10:45 [Bug middle-end/34300] New: gcc 4.2.2 miscompiles code that uses global register variables bruno at clisp dot org
                   ` (4 preceding siblings ...)
  2007-11-30 12:00 ` ismail at pardus dot org dot tr
@ 2007-12-26 14:31 ` pinskia at gcc dot gnu dot org
  2009-03-13 20:30 ` rob1weld at aol dot com
  2009-03-13 21:10 ` hjl dot tools at gmail dot com
  7 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2007-12-26 14:31 UTC (permalink / raw)
  To: gcc-bugs



-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|major                       |normal


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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/34300] gcc 4.2.2 miscompiles code that uses global register variables
  2007-11-30 10:45 [Bug middle-end/34300] New: gcc 4.2.2 miscompiles code that uses global register variables bruno at clisp dot org
                   ` (5 preceding siblings ...)
  2007-12-26 14:31 ` pinskia at gcc dot gnu dot org
@ 2009-03-13 20:30 ` rob1weld at aol dot com
  2009-03-13 21:10 ` hjl dot tools at gmail dot com
  7 siblings, 0 replies; 10+ messages in thread
From: rob1weld at aol dot com @ 2009-03-13 20:30 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from rob1weld at aol dot com  2009-03-13 20:30 -------
Confirmed on the Trunk.

In the Bug mentioned at http://bugs.gentoo.org/54738 and here
this fails on gcc version 4.4.0 20090312 [trunk revision 144821].

Rob


-- 


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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/34300] gcc 4.2.2 miscompiles code that uses global register variables
  2007-11-30 10:45 [Bug middle-end/34300] New: gcc 4.2.2 miscompiles code that uses global register variables bruno at clisp dot org
                   ` (6 preceding siblings ...)
  2009-03-13 20:30 ` rob1weld at aol dot com
@ 2009-03-13 21:10 ` hjl dot tools at gmail dot com
  7 siblings, 0 replies; 10+ messages in thread
From: hjl dot tools at gmail dot com @ 2009-03-13 21:10 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #7 from hjl dot tools at gmail dot com  2009-03-13 21:10 -------
It works for me on Linux/Intel64 with gcc 4.4.0 revision 144836.


-- 

hjl dot tools at gmail dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |hjl dot tools at gmail dot
                   |                            |com


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


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Bug middle-end/34300] gcc 4.2.2 miscompiles code that uses global register variables
       [not found] <bug-34300-4@http.gcc.gnu.org/bugzilla/>
@ 2014-02-16 13:15 ` jackie.rosen at hushmail dot com
  0 siblings, 0 replies; 10+ messages in thread
From: jackie.rosen at hushmail dot com @ 2014-02-16 13:15 UTC (permalink / raw)
  To: gcc-bugs

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

Jackie Rosen <jackie.rosen at hushmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jackie.rosen at hushmail dot com

--- Comment #8 from Jackie Rosen <jackie.rosen at hushmail dot com> ---
*** Bug 260998 has been marked as a duplicate of this bug. ***
Seen from the domain http://volichat.com
Page where seen: http://volichat.com/adult-chat-rooms
Marked for reference. Resolved as fixed @bugzilla.


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-02-16 13:15 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-30 10:45 [Bug middle-end/34300] New: gcc 4.2.2 miscompiles code that uses global register variables bruno at clisp dot org
2007-11-30 10:47 ` [Bug middle-end/34300] " bruno at clisp dot org
2007-11-30 10:50 ` pinskia at gcc dot gnu dot org
2007-11-30 11:10 ` rguenth at gcc dot gnu dot org
2007-11-30 11:56 ` ismail at pardus dot org dot tr
2007-11-30 12:00 ` ismail at pardus dot org dot tr
2007-12-26 14:31 ` pinskia at gcc dot gnu dot org
2009-03-13 20:30 ` rob1weld at aol dot com
2009-03-13 21:10 ` hjl dot tools at gmail dot com
     [not found] <bug-34300-4@http.gcc.gnu.org/bugzilla/>
2014-02-16 13:15 ` jackie.rosen at hushmail dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).