public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
From: Andreas Jaeger <aj@suse.de>
To: gcc-gnats@gcc.gnu.org
Subject: optimization/9196: [3.4 regression] Inlining of function with void * arithmetic is misoptimized
Date: Mon, 06 Jan 2003 18:36:00 -0000	[thread overview]
Message-ID: <E18VbwY-0001cL-00@arthur.inka.de> (raw)


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


             reply	other threads:[~2003-01-06 18:36 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-01-06 18:36 Andreas Jaeger [this message]
2003-02-18 10:08 ebotcazou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E18VbwY-0001cL-00@arthur.inka.de \
    --to=aj@suse.de \
    --cc=gcc-gnats@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).