Bug 14937 - GCSE bug with global register variables
Summary: GCSE bug with global register variables
Status: RESOLVED DUPLICATE of bug 7871
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.3.1
: P3 normal
Target Milestone: 3.3.4
Assignee: Not yet assigned to anyone
Keywords: wrong-code
Depends on:
Reported: 2004-04-13 10:09 UTC by Bruno Haible
Modified: 2005-07-23 22:49 UTC (History)
1 user (show)

See Also:
Host: i586-suse-linux-gnu
Target: i586-suse-linux-gnu
Build: i586-suse-linux-gnu
Known to work:
Known to fail:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description Bruno Haible 2004-04-13 10:09:59 UTC
In a function using a global register variable, that conditionally calls
a nonreturning function, the GCSE omits the last update (a decrement)
of the global register variable.

System: Linux linuix 2.4.21-99-default #1 Wed Sep 24 13:30:51 UTC 2003 i686 athlon i386 GNU/Linux
Architecture: i686

	<machine, os, target, libraries (multiple lines)>
host: i586-suse-linux-gnu
build: i586-suse-linux-gnu
target: i586-suse-linux-gnu
configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --enable-languages=c,c++,f77,objc,java,ada --disable-checking --enable-libgcj --with-gxx-include-dir=/usr/include/g++ --with-slibdir=/lib --with-system-zlib --enable-shared --enable-__cxa_atexit i586-suse-linux


================================= bug.c ====================================
typedef void * object;
register object* STACK __asm__("%ebx");
typedef struct {
  object GCself;
  unsigned int tfl;
  unsigned int data[0];
} * Sstring;
typedef struct {
  object GCself;
  unsigned int tfl;
  object enc_eol;
  object enc_towcs_error;
  object enc_tombs_error;
  object enc_charset;
  object enc_mblen;
  object enc_mbstowcs;
  object enc_wcslen;
  object enc_wcstombs;
  object enc_range;
  object enc_table;
  unsigned int min_bytes_per_char;
  unsigned int max_bytes_per_char;
} * Encoding;
extern void __attribute__((__noreturn__)) fehler_notreached (const char * file, unsigned int line);
extern object allocate_s32string (unsigned int len);
object n_char_to_string (const char * srcptr, unsigned int blen, object encoding)
  const unsigned char * bptr = (const unsigned char *)srcptr;
  const unsigned char * bendptr = bptr + blen;
  unsigned int clen = ((unsigned int (*) (object, const unsigned char *, const unsigned char *)) ((const void *)((void*)((unsigned long)(((Encoding)((unsigned long)(encoding)-1))->enc_mblen)))))(encoding,bptr,bendptr);
  (STACK[0] = encoding, STACK += 1);
    object obj = allocate_s32string(clen);
    encoding = (STACK -= 1, STACK[0]);
      unsigned int * cptr = &((Sstring)((unsigned long)(obj)-1))->data[0];
      unsigned int * cendptr = cptr + clen;
      ((void (*) (object, object, const unsigned char **, const unsigned char *, unsigned int**, unsigned int*)) ((const void *)((void*)((unsigned long)(((Encoding)((unsigned long)(encoding)-1))->enc_mbstowcs)))))(encoding,(object)0,&bptr,bendptr,&cptr,cendptr);
      if (!(cptr == cendptr))
    return obj;
$ gcc -O2 -Wall -S bug.c

In the resulting bug.s, you see that %ebx is incremented by 4 (this
corresponds to the STACK += 1 expression) but is never decremented back
by 4 (as expected from the STACK -= 1 expression two lines below).

================================= bug.s ====================================
        .file   "bug.c"
        .section        .rodata.str1.1,"aMS",@progbits,1
        .string "encoding.d"
        .p2align 4,,15
.globl n_char_to_string
        .type   n_char_to_string, @function
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %edi
        pushl   %esi
        subl    $36, %esp
        movl    8(%ebp), %eax
        movl    12(%ebp), %edx
        movl    16(%ebp), %edi
        addl    %eax, %edx
        movl    %edx, -20(%ebp)
        movl    %eax, -16(%ebp)
        pushl   %edx
        pushl   %eax
        pushl   %edi
        call    *23(%edi)
        movl    %eax, %esi
        movl    %edi, (%ebx)
        movl    %eax, (%esp)
        addl    $4, %ebx
        call    allocate_s32string
        movl    %eax, -24(%ebp)
        movl    -4(%ebx), %edi
        addl    $7, %eax
        movl    %eax, -12(%ebp)
        leal    (%eax,%esi,4), %esi
        movl    %esi, -28(%ebp)
        popl    %ecx
        popl    %eax
        leal    -12(%ebp), %eax
        pushl   %esi
        pushl   %eax
        leal    -16(%ebp), %eax
        movl    -20(%ebp), %edx
        pushl   %edx
        pushl   %eax
        pushl   $0
        pushl   %edi
        call    *27(%edi)
        movl    -28(%ebp), %eax
        addl    $32, %esp
        cmpl    %eax, -12(%ebp)
        jne     .L4
        movl    -24(%ebp), %eax
        leal    -8(%ebp), %esp
        popl    %esi
        popl    %edi
        popl    %ebp
        pushl   %eax
        pushl   %eax
        pushl   $1910
        pushl   $.LC0
        call    fehler_notreached
        .size   n_char_to_string, .-n_char_to_string
        .ident  "GCC: (GNU) 3.3.1 (SuSE Linux)"
Comment 1 Bruno Haible 2004-04-13 10:09:59 UTC

The bug goes away if -fno-gcse is passed to gcc.
Comment 2 Andrew Pinski 2004-04-13 11:17:05 UTC
This is a dup of bug 7871 which is fixed in 3.3.4.

*** This bug has been marked as a duplicate of 7871 ***