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 optimization/14937] New: GCSE bug with global register variables


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.

Environment:
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

How-To-Repeat:

================================= 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))
        fehler_notreached("encoding.d",1910);
    }
    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
.LC0:
        .string "encoding.d"
        .text
        .p2align 4,,15
.globl n_char_to_string
        .type   n_char_to_string, @function
n_char_to_string:
        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
        ret
.L4:
        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)"
============================================================================
------- Additional Comments From bruno at clisp dot org  2004-04-13 10:09 -------
Fix:

The bug goes away if -fno-gcse is passed to gcc.

-- 
           Summary: GCSE bug with global register variables
           Product: gcc
           Version: 3.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: bruno at clisp dot org
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: i586-suse-linux-gnu
  GCC host triplet: i586-suse-linux-gnu
GCC target triplet: i586-suse-linux-gnu


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


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