On Wed, Aug 21, 2002 at 11:55:27AM +0300, Alexei Khlebnikov wrote:
> > I think this program should not terminate at all because i will
> > always be one greater than oldi.
> > I think gcc3.0 has a problem with no optimization then but since
> > there is later version that works gcc 3.1.1, upgrade.
> 
> With no optimization the program runs correctly by the rules of integers
> representation in memory. See the explanation below.
> 

Changed my mind. After a posting from Linus on dri-devel and a discussion
about integer overflow (undefined) in C the following came out:

---
unsigned int i = 0;
unsigned int oldi = 0;
while ((int) ++i > (int) oldi) oldi = i;
return oldi;
---

Looks good... incrementing unsigned (defined overflow) and doing an
unsigned check (both operands).

When compiling the above code with -ON (N>0), everyone gets it wrong.

gcc-2.9 optimizes it away:

080483c0 <main>:
 80483c0:       55                      push   %ebp
 80483c1:       89 e5                   mov    %esp,%ebp
 80483c3:       eb fe                   jmp    80483c3 <main+0x3>
 80483c5:       90                      nop
 ...

gcc-3.0 and 3.1 optimize it away:

08048304 <main>:
 8048304:       55                      push   %ebp
 8048305:       89 e5                   mov    %esp,%ebp
 8048307:       83 ec 08                sub    $0x8,%esp
 804830a:       83 e4 f0                and    $0xfffffff0,%esp
 804830d:       8d 76 00                lea    0x0(%esi),%esi
 8048310:       eb fe                   jmp    8048310 <main+0xc>
 8048312:       90                      nop
 8048313:       90                      nop

The following works, but the evaluated expression is no longer part
of the while.

        unsigned int i = 0;
        unsigned int oldi = 0;
        while(1) if ( (int) ++i < (int) oldi ) { break; } else oldi=i;
        return (int)oldi;

This possibly breaks the loop optimization?

Anyone care to jump in? :)

c.


Reply via email to