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]

optimization/5172: Optimization bug in GCC 3.1 CVS: strcpy (one, "") call removed (Bugin -finline-functions?)



>Number:         5172
>Category:       optimization
>Synopsis:       Optimisation bug: strcpy (one,"") removed (Bug in -finline-functions?)
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Fri Dec 21 23:06:03 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Andreas Jaeger
>Release:        3.1 20011220 (experimental)
>Organization:
>Environment:
System: Linux gromit 2.4.16 #3 Tue Dec 18 20:48:07 CET 2001 i686 unknown
Architecture: i686

	
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: /cvs/gcc/configure --prefix=/opt/gcc-3.1-devel --enable-shared --enable-threads=posix --enable-clocale=gnu --with-gnu-as --with-gnu-ld --disable-nls --with-system-zlib
>Description:
	Testing glibc on i686-linux, I've noticed a bug in the
	inl-tester file which tests several string inline
	implementations of glibc.  Running the appended test program
	gives:

	$ /opt/gcc-3.1-devel/bin/gcc inl-tester.c  -O3 -gstabs -march=pentiumpro -mcpu=i686 -o /tmp/inl-tester;/tmp/inl-tester 
strpbrk flunked test 10
1 errors.


Running the test program in gdb, I noticed that the first strpy (one,
"") is not executed at all:

Breakpoint 1, main () at inl-tester.c:85
85        int status;
(gdb) n
72        it = "strpbrk";
(gdb) 
85        int status;
(gdb) 
main () at inl-tester.c:74
74        (void) strcpy(one, "abcabdea");
(gdb) 
85        int status;
(gdb) 
72        it = "strpbrk";
(gdb) 
85        int status;
(gdb) 
74        (void) strcpy(one, "abcabdea");
(gdb) 
85        int status;
(gdb) 
16      {
(gdb) 
85        int status;
(gdb) 
74        (void) strcpy(one, "abcabdea");
(gdb) 
19        __asm__ __volatile__
(gdb) 
85        int status;
(gdb) 
74        (void) strcpy(one, "abcabdea");
(gdb) 
19        __asm__ __volatile__
(gdb) 
52        if (!thing)
(gdb) 
strpbrk flunked test 10
55            ++errors;
(gdb) 
79      (void) strcpy(one, "");
(gdb) 
91      if (errors == 0)


>How-To-Repeat:

	Compile the test program with -O3 (works with -O2 but fails
	with -O2 -finline-functions).
	
	Here's the test program:
	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef unsigned int size_t;


extern int printf (__const char *__restrict __format, ...) ;
extern int puts (__const char *__s) ;

extern char *strcpy (char *__restrict __dest, __const char *__restrict __src)
     ;

extern int strcmp (__const char *__s1, __const char *__s2)
     __attribute__ ((__pure__));

extern __inline char *__strpbrk_g (__const char *__s, __const char *__accept);
extern __inline char *
__strpbrk_g (__const char *__s, __const char *__accept)
{
  register unsigned long int __d0, __d1, __d2, __d3;
  register char *__res;
  __asm__ __volatile__
    ("movl	%%ebx,%%edi\n\t"
     "cld\n\t"
     "repne; scasb\n\t"
     "notl	%%ecx\n\t"
     "leal	-1(%%ecx),%%edx\n"
     "1:\n\t"
     "lodsb\n\t"
     "testb	%%al,%%al\n\t"
     "je	2f\n\t"
     "movl	%%ebx,%%edi\n\t"
     "movl	%%edx,%%ecx\n\t"
     "repne; scasb\n\t"
     "jne	1b\n\t"
     "decl	%0\n\t"
     "jmp	3f\n"
     "2:\n\t"
     "xorl	%0,%0\n"
     "3:"
     : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
     : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
     : "cc");
  return __res;
}


const char *it = "<UNSET>";
size_t errors = 0;


static void
check (int thing, int number)
{
  if (!thing)
    {
      printf("%s flunked test %d\n", it, number);
      ++errors;
    }
}


static void
equal (const char *a, const char *b, int number)
{
  check(a != ((void *)0) && b != ((void *)0) && strcmp (a, b) == 0, number);
}

char one[50];


static void
test_strpbrk (void)
{
  it = "strpbrk";

  (void) strcpy(one, "abcabdea");
  (void) strcpy(one, "");

  check ((__strpbrk_g (one, "bc")) == ((void *)0), 10);

  (void) strcpy(one, "");

}

int
main (void)
{
  int status;


  test_strpbrk ();

  if (errors == 0)
    {
      status = 0;
      puts("No errors.");
    }
  else
    {
      status = 1;
      printf("%Zd errors.\n", errors);
    }

  return status;
}

	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	And here's the preproccessed source:
	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 1 "inl-tester.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "inl-tester.c"
typedef unsigned int size_t;


extern int printf (__const char *__restrict __format, ...) ;
extern int puts (__const char *__s) ;

extern char *strcpy (char *__restrict __dest, __const char *__restrict __src)
     ;

extern int strcmp (__const char *__s1, __const char *__s2)
     __attribute__ ((__pure__));

extern __inline char *__strpbrk_g (__const char *__s, __const char *__accept);
extern __inline char *
__strpbrk_g (__const char *__s, __const char *__accept)
{
  register unsigned long int __d0, __d1, __d2, __d3;
  register char *__res;
  __asm__ __volatile__
    ("movl	%%ebx,%%edi\n\t"
     "cld\n\t"
     "repne; scasb\n\t"
     "notl	%%ecx\n\t"
     "leal	-1(%%ecx),%%edx\n"
     "1:\n\t"
     "lodsb\n\t"
     "testb	%%al,%%al\n\t"
     "je	2f\n\t"
     "movl	%%ebx,%%edi\n\t"
     "movl	%%edx,%%ecx\n\t"
     "repne; scasb\n\t"
     "jne	1b\n\t"
     "decl	%0\n\t"
     "jmp	3f\n"
     "2:\n\t"
     "xorl	%0,%0\n"
     "3:"
     : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
     : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
     : "cc");
  return __res;
}


const char *it = "<UNSET>";
size_t errors = 0;


static void
check (int thing, int number)
{
  if (!thing)
    {
      printf("%s flunked test %d\n", it, number);
      ++errors;
    }
}


static void
equal (const char *a, const char *b, int number)
{
  check(a != ((void *)0) && b != ((void *)0) && strcmp (a, b) == 0, number);
}

char one[50];


static void
test_strpbrk (void)
{
  it = "strpbrk";

  (void) strcpy(one, "abcabdea");
  (void) strcpy(one, "");

  check ((__strpbrk_g (one, "bc")) == ((void *)0), 10);

  (void) strcpy(one, "");

}

int
main (void)
{
  int status;


  test_strpbrk ();

  if (errors == 0)
    {
      status = 0;
      puts("No errors.");
    }
  else
    {
      status = 1;
      printf("%Zd errors.\n", errors);
    }

  return status;
}

	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>Fix:
	


-- 
 Andreas Jaeger
  SuSE Labs aj@suse.de
   private aj@arthur.inka.de
    http://www.suse.de/~aj
>Release-Note:
>Audit-Trail:
>Unformatted:


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