public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* pointer post-incr problem with GCC 3.3.3 ??
@ 2004-06-18 13:01 Ron Flory
  2004-06-18 14:11 ` Graham Stott
  0 siblings, 1 reply; 5+ messages in thread
From: Ron Flory @ 2004-06-18 13:01 UTC (permalink / raw)
  To: gcc-bugs, Ron Flory, Home; +Cc: ron flory

hi-

  I believe I may have found an optimizer issue with x86 gcc C++
3.3.3 in the postfix-incr / assignment operation(s).

  I have searched the gcc bug tracking database for this issue and
have been unable to located an existing report of this issue.

------------------------------

background:

gcc -v :

Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.3.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man 
--infodir=/usr/share/info --enable-shared --enable-threads=posix 
--disable-checking --disable-libunwind-exceptions --with-system-zlib 
--enable-__cxa_atexit --host=i386-redhat-linux
Thread model: posix
gcc version 3.3.3 20040412 (Red Hat Linux 3.3.3-7)

  This is gcc/c++ included with Fedora Core 2, Running on a
SMP P-III, Asus MB.

------------------------------

  The compilation line I used, w/ switches is:

gcc -o maze -O6 maze.cpp -lstdc++

----------------

Given two trivialized code fragments:

#1:
       while (*ptr)
       {
          *ptr = toupper(*ptr);

          ptr++;
       }

#2:
       while (*ptr)
          *(ptr++) = toupper(*ptr);

  I would assert these two code frags are functionally identical.

  Frag #1 appears to compile and operate correctly at all optimizer
settings, however frag #2 produces incorrect results for any
optimizer setting greater than "-O" (i.e., no optimization or -O
operate correctly).

  This is a simple 'strupr()' body, which should capitalize any
ascii c-string in-place.  If frag #2 is compiled with optimization
greater than "-O", the string "-abc" is altered to be "ABC" instead
of "-ABC", which becomes a string shelf-left operation- NOT the
desired effect.

-------------------------------------

  analysis of generated code:

// ***************************************
// ***** compiled with -O : works OK *****
// ***************************************

00001f38 <_Z6struprPc>:

void  strupr(char *ptr)
{
  1f38: 55              push   %ebp
  1f39: 89 e5           mov    %esp,%ebp
  1f3b: 56              push   %esi
  1f3c: 53              push   %ebx
  1f3d: 8b 75 08        mov    0x8(%ebp),%esi
if (ptr)
  1f40: 85 f6           test   %esi,%esi
  1f42: 74 1e           je     1f62 <_Z6struprPc+0x2a>
    while (*ptr)
  1f44: 80 3e 00        cmpb   $0x0,(%esi)
  1f47: 74 19           je     1f62 <_Z6struprPc+0x2a>
       *(ptr++) = toupper(*ptr);
  1f49: 83 ec 0c        sub    $0xc,%esp
  1f4c: 0f be 06        movsbl (%esi),%eax  // deref *ptr
  1f4f: 50              push   %eax
  1f50: 89 f3           mov    %esi,%ebx    // backup 'ptr' for later
  1f52: 46              inc    %esi         // inc 'ptr'
  1f53: e8 fc ff ff ff  call   1f54 <_Z6struprPc+0x1c>
  1f58: 88 03           mov    %al,(%ebx)   // store at pre-inc 'ptr'
  1f5a: 83 c4 10        add    $0x10,%esp
  1f5d: 80 3e 00        cmpb   $0x0,(%esi)
  1f60: 75 e7           jne    1f49 <_Z6struprPc+0x11>
}
  1f62: 8d 65 f8        lea    0xfffffff8(%ebp),%esp
  1f65: 5b              pop    %ebx
  1f66: 5e              pop    %esi
  1f67: 5d              pop    %ebp
  1f68: c3              ret
  1f69: 90              nop

  The key points in this snippet are:

  1f4c: load char from *ptr
  1f50: make temp copy of 'ptr' for result, simulate post-incr
  1f52: incr 'ptr' in place, not used again in this iteration
  1f58: save result using tmp 'ptr' value, prior to post-incr

  The generated code is correct.

------------------------------------

// ***********************************
// ***** compiled with -O6 : BUG *****
// ***********************************

00001ff0 <_Z6struprPc>:

void  strupr(char *ptr)
{
  1ff0: 55              push   %ebp
  1ff1: 89 e5           mov    %esp,%ebp
  1ff3: 56              push   %esi
  1ff4: 53              push   %ebx
  1ff5: 8b 75 08        mov    0x8(%ebp),%esi
if (ptr)
  1ff8: 85 f6           test   %esi,%esi
  1ffa: 74 05           je     2001 <_Z6struprPc+0x11>
    while (*ptr)
  1ffc: 80 3e 00        cmpb   $0x0,(%esi)
  1fff: 75 07           jne    2008 <_Z6struprPc+0x18>
       *(ptr++) = toupper(*ptr);
}
  2001: 8d 65 f8        lea    0xfffffff8(%ebp),%esp
  2004: 5b              pop    %ebx
  2005: 5e              pop    %esi
  2006: 5d              pop    %ebp
  2007: c3              ret
  2008: 89 f3           mov    %esi,%ebx   // make tmp copy of 'ptr'
  200a: 83 ec 0c        sub    $0xc,%esp
  200d: 46              inc    %esi        // incr ptr
  200e: 0f be 16        movsbl (%esi),%edx // deref 'ptr' AFTER incr
  2011: 52              push   %edx
  2012: e8 fc ff ff ff  call   2013 <_Z6struprPc+0x23>
  2017: 83 c4 10        add    $0x10,%esp
  201a: 88 03           mov    %al,(%ebx)
  201c: 80 3e 00        cmpb   $0x0,(%esi)
  201f: 75 e7           jne    2008 <_Z6struprPc+0x18>
  2021: eb de           jmp    2001 <_Z6struprPc+0x11>

  The key points in this snippet are:

  2008: make temp copy of 'ptr' for result, simulate post-incr
  200d: incr 'ptr' in place
        BELOW IS AN ERROR
  200e: load char from *ptr, but 'ptr' has already been incr
        ABOVE IS AN ERROR
  201a: save result using tmp 'ptr' value, prior to post-incr

  The problem with this snippet is that 'ptr' is derefed
after it was incr'd at 200d.  There are two solutions to
this error:

  1. use ebx as the src ptr at 200e instead of esi, which
     has already been 'post-incremented' early.
  2. move the 'movsbl' instr ahead of the 'incr' at
     200d.

---------------------------------------------

  Operations of the form *(ptr++) are fundamental to C/C++, and the
increment should be applied only after the assignment (pointer deref),
but it is apparently it is occurring too early...  I am somewhat
surprised this has gotten past the compiler verification test suites
that should be run during testing and prior to release.

  I may try to build the most recent gnu C/C++ from sources to
see if the problem is still present- I have not done this in a
few years; hope it goes well.

ron flory


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

* Re: pointer post-incr problem with GCC 3.3.3 ??
  2004-06-18 13:01 pointer post-incr problem with GCC 3.3.3 ?? Ron Flory
@ 2004-06-18 14:11 ` Graham Stott
  2004-06-18 14:21   ` Falk Hueffner
  0 siblings, 1 reply; 5+ messages in thread
From: Graham Stott @ 2004-06-18 14:11 UTC (permalink / raw)
  To: Ron Flory, gcc-bugs, Ron Flory, Home; +Cc: ron flory

Hi,

>           *(ptr++) = toupper(*ptr);
> 
>   I would assert these two code frags are functionally identical.
>
Nope your assertion is wrong.

Read up on "sequence points" and you'll undersrand why. 

Graham 


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

* Re: pointer post-incr problem with GCC 3.3.3 ??
  2004-06-18 14:11 ` Graham Stott
@ 2004-06-18 14:21   ` Falk Hueffner
  2004-06-18 14:33     ` Falk Hueffner
  2004-06-18 14:44     ` Andreas Schwab
  0 siblings, 2 replies; 5+ messages in thread
From: Falk Hueffner @ 2004-06-18 14:21 UTC (permalink / raw)
  To: Graham Stott; +Cc: Ron Flory, gcc-bugs, Ron Flory, Home

Graham Stott <graham.stott@btinternet.com> writes:

>>           *(ptr++) = toupper(*ptr);
>> 
>>   I would assert these two code frags are functionally identical.
>>
> Nope your assertion is wrong.
>
> Read up on "sequence points" and you'll undersrand why. 

I don't see this. Can you please explain in detail where the violation
is?

-- 
	Falk


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

* Re: pointer post-incr problem with GCC 3.3.3 ??
  2004-06-18 14:21   ` Falk Hueffner
@ 2004-06-18 14:33     ` Falk Hueffner
  2004-06-18 14:44     ` Andreas Schwab
  1 sibling, 0 replies; 5+ messages in thread
From: Falk Hueffner @ 2004-06-18 14:33 UTC (permalink / raw)
  To: Graham Stott; +Cc: Ron Flory, gcc-bugs, Ron Flory, Home

Falk Hueffner <hueffner@informatik.uni-tuebingen.de> writes:

> Graham Stott <graham.stott@btinternet.com> writes:
>
>>>           *(ptr++) = toupper(*ptr);
>>> 
>>>   I would assert these two code frags are functionally identical.
>>>
>> Nope your assertion is wrong.
>>
>> Read up on "sequence points" and you'll undersrand why. 
>
> I don't see this. Can you please explain in detail where the violation
> is?

Actually, I think I see it now. "ptr" has its value read before the
modification of "ptr", without an intervening sequence point, and not
only to determine the value to be stored in "ptr".

-- 
	Falk


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

* Re: pointer post-incr problem with GCC 3.3.3 ??
  2004-06-18 14:21   ` Falk Hueffner
  2004-06-18 14:33     ` Falk Hueffner
@ 2004-06-18 14:44     ` Andreas Schwab
  1 sibling, 0 replies; 5+ messages in thread
From: Andreas Schwab @ 2004-06-18 14:44 UTC (permalink / raw)
  To: Falk Hueffner; +Cc: Graham Stott, Ron Flory, gcc-bugs, Ron Flory, Home

Falk Hueffner <hueffner@informatik.uni-tuebingen.de> writes:

> Graham Stott <graham.stott@btinternet.com> writes:
>
>>>           *(ptr++) = toupper(*ptr);
>>> 
>>>   I would assert these two code frags are functionally identical.
>>>
>> Nope your assertion is wrong.
>>
>> Read up on "sequence points" and you'll undersrand why. 
>
> I don't see this. Can you please explain in detail where the violation
> is?

Order of evaluation of operator arguments is unspecified, as well as the
exact point (before the next sequence point) when side effects take place.

Andreas.

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Maxfeldstraße 5, 90409 Nürnberg, Germany
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."


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

end of thread, other threads:[~2004-06-18 14:44 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-06-18 13:01 pointer post-incr problem with GCC 3.3.3 ?? Ron Flory
2004-06-18 14:11 ` Graham Stott
2004-06-18 14:21   ` Falk Hueffner
2004-06-18 14:33     ` Falk Hueffner
2004-06-18 14:44     ` Andreas Schwab

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