public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
* Re: optimization/9196: [3.4 regression] Inlining of function with void * arithmetic is misoptimized
@ 2003-02-18 10:08 ebotcazou
  0 siblings, 0 replies; 2+ messages in thread
From: ebotcazou @ 2003-02-18 10:08 UTC (permalink / raw)
  To: aj, gcc-bugs, gcc-prs, nobody

Synopsis: [3.4 regression] Inlining of function with void * arithmetic is misoptimized

State-Changed-From-To: open->analyzed
State-Changed-By: ebotcazou
State-Changed-When: Tue Feb 18 10:08:24 2003
State-Changed-Why:
    Regression from 3.3 according to Andreas.

http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=9196


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

* optimization/9196: [3.4 regression] Inlining of function with void * arithmetic is misoptimized
@ 2003-01-06 18:36 Andreas Jaeger
  0 siblings, 0 replies; 2+ messages in thread
From: Andreas Jaeger @ 2003-01-06 18:36 UTC (permalink / raw)
  To: gcc-gnats


>Number:         9196
>Category:       optimization
>Synopsis:       [3.4 regression] Inlining of function with void * arithmetic is misoptimized
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          wrong-code
>Submitter-Id:   net
>Arrival-Date:   Mon Jan 06 10:36:02 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Andreas Jaeger
>Release:        3.4 20030103 (experimental)
>Organization:
private
>Environment:
System: Linux gromit 2.4.18 #1 Sat Apr 6 22:05:01 CEST 2002 i686 unknown
Architecture: i686

	
host: i686-pc-linux-gnu
build: i686-pc-linux-gnu
target: i686-pc-linux-gnu
configured with: 
>Description:
	Using GCC 3.4 I got a failure in the glibc testsuite.  The
	problem can be shown with the appended simplified program:

	gromit:~/tmp:[0]$ /opt/gcc/3.4-devel/bin/gcc -O2 inl.c && ./a.out 
memrchr flunked test 1
1 errors.

>How-To-Repeat:
	Compile this program (this is preproccessed):

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
typedef unsigned int size_t;


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

extern int puts (__const char *__s) ;


extern __inline void *__memrchr (__const void *__s, int __c, size_t __n);

extern __inline void *
__memrchr (__const void *__s, int __c, size_t __n)
{
  register unsigned long int __d0;

  register void *__res;
  if (__n == 0)
    return ((void *)0);

  __asm__ __volatile__
    ("std\n\t"
     "repne; scasb\n\t"
     "je 1f\n\t"
     "orl $-1,%0\n"
     "1:\tcld"
     : "=D" (__res), "=&c" (__d0)
     : "a" (__c), "0" (__s + __n - 1), "1" (__n),
       "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
     : "cc");

  return __res + 1;
}

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;
    }
}

char one[50];
char two[50];
char *cp;

static void
test_memrchr (void)
{
  it = "memrchr";
  
  check (__memrchr ("abcd", 'z', 5) == ((void *)0), 1);
}

int
main (void)
{
  int status;


  test_memrchr ();

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

  return status;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

	Note that GCC 3.3 and earlier releases optimized this
	correctly, this is therefore a regression.

	objdump -dr of the binary shows that the test_memrchr function
	is misoptimized:
080483d0 <test_memrchr>:
 80483d0:       55                      push   %ebp
 80483d1:       ba e0 84 04 08          mov    $0x80484e0,%edx
 80483d6:       89 e5                   mov    %esp,%ebp
 80483d8:       57                      push   %edi
 80483d9:       b8 7a 00 00 00          mov    $0x7a,%eax
 80483de:       83 ec 14                sub    $0x14,%esp
 80483e1:       89 15 14 95 04 08       mov    %edx,0x8049514
 80483e7:       b9 05 00 00 00          mov    $0x5,%ecx
 80483ec:       bf ec 84 04 08          mov    $0x80484ec,%edi
 80483f1:       fd                      std    
 80483f2:       f2 ae                   repnz scas %es:(%edi),%al
 80483f4:       74 03                   je     80483f9 <test_memrchr+0x29>
 80483f6:       83 cf ff                or     $0xffffffff,%edi
 80483f9:       fc                      cld    
 80483fa:       c7 44 24 04 01 00 00    movl   $0x1,0x4(%esp,1)
 8048401:       00 
 8048402:       c7 04 24 00 00 00 00    movl   $0x0,(%esp,1)
 8048409:       e8 82 ff ff ff          call   8048390 <check>

	The result of memrchr is not used - especially not compared
	against NULL and the result passed to check - and instead a
	$0x0 is passed as first argument to check (at address
	8048402).

>Fix:
	No fix known for GCC itself.

	The program can be fixed to work by changing the program to
	use (pseudo patch):

-  register void *__res;
+  register int __res;
-    return __res + 1;
+    return (void *) __res + 1;

	But this should not be necessary, the arithmetic on void is a
	GNU extension and therefore legal GNU C code.
>Release-Note:
>Audit-Trail:
>Unformatted:


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

end of thread, other threads:[~2003-02-18 10:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-02-18 10:08 optimization/9196: [3.4 regression] Inlining of function with void * arithmetic is misoptimized ebotcazou
  -- strict thread matches above, loose matches on Subject: below --
2003-01-06 18:36 Andreas Jaeger

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).