public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* GCC Unrolling Simple Loop Generates Rubbish Code?
@ 2005-07-19  2:51 Lei Ming
  2005-07-19  4:00 ` Ian Lance Taylor
  2005-07-19 16:14 ` jlh
  0 siblings, 2 replies; 3+ messages in thread
From: Lei Ming @ 2005-07-19  2:51 UTC (permalink / raw)
  To: gcc-help

Dear GCC Hackers,

This simple code:

int
main (void)
{
  int s = 0;
  int i;
  for (i = 0; i < 100; i++)
    s += i;
  return 0;
}

After compiled with "-O3 -funroll-all-loops",  will generate this piece of 
assembly code for the loop:

        movl    $99, %eax
.L6:
        subl    $25, %eax        <==
        jns     .L6
        xorl    %eax, %eax
        leave
        ret

I wonder what's the purpose of "subl    $25, %eax"? If the compiler knows that 
the whole loop is useless, since we don't really use the result, why not just 
eliminate this loop and simply return zero? If it choose to execute the loop, 
why it is the number 25 instead of other number? Why not 42? :-)

The logic here seems confusing to me, but I don't know much about GCC's 
optimizing algorithms. Could someone kindly explain it to me?

I'm using GCC 3.2.3:

Reading specs from /usr/lib/gcc-lib/i386-asianux-linux/3.2.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man 
--infodir=/usr/share/info --enable-shared --enable-threads=posix 
--disable-checking --with-system-zlib --enable-__cxa_atexit 
--host=i386-asianux-linux
Thread model: posix
gcc version 3.2.3 20030502

I've asked other people to test this with their different GCC version, and all 
their GCC versions generate this kind of  code, with maybe different numbers 
than 25. Even GCC 4, it was said. I don't have GCC 4 currently.

Yesterday I asked this in #gcc on IRC, they suggested that this is a bug. But 
I think I should ask it here before sending a stupid fake bug report :-)

So what will you say?

Best Regards,
Lei Ming

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

* Re: GCC Unrolling Simple Loop Generates Rubbish Code?
  2005-07-19  2:51 GCC Unrolling Simple Loop Generates Rubbish Code? Lei Ming
@ 2005-07-19  4:00 ` Ian Lance Taylor
  2005-07-19 16:14 ` jlh
  1 sibling, 0 replies; 3+ messages in thread
From: Ian Lance Taylor @ 2005-07-19  4:00 UTC (permalink / raw)
  To: Lei Ming; +Cc: gcc-help

Lei Ming <ming.lei@oracle.com> writes:

> This simple code:
> 
> int
> main (void)
> {
>   int s = 0;
>   int i;
>   for (i = 0; i < 100; i++)
>     s += i;
>   return 0;
> }
> 
> After compiled with "-O3 -funroll-all-loops",  will generate this piece of 
> assembly code for the loop:
> 
>         movl    $99, %eax
> .L6:
>         subl    $25, %eax        <==
>         jns     .L6
>         xorl    %eax, %eax
>         leave
>         ret

I tried compiling with current gcc mainline with -O3
-funroll-all-loops.  I got this:

   0:   55                      push   %ebp
   1:   31 c0                   xor    %eax,%eax
   3:   89 e5                   mov    %esp,%ebp
   5:   83 ec 08                sub    $0x8,%esp
   8:   83 e4 f0                and    $0xfffffff0,%esp
   b:   83 ec 10                sub    $0x10,%esp
   e:   c9                      leave
   f:   c3                      ret

So I think things are better now.

I also see the behaviour you report with gcc 3.2.3.  It does seem
pretty incomprehensible.  Since it seems to be fixed, I haven't
bothered to figure out why it used to behave like that.

Ian

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

* Re: GCC Unrolling Simple Loop Generates Rubbish Code?
  2005-07-19  2:51 GCC Unrolling Simple Loop Generates Rubbish Code? Lei Ming
  2005-07-19  4:00 ` Ian Lance Taylor
@ 2005-07-19 16:14 ` jlh
  1 sibling, 0 replies; 3+ messages in thread
From: jlh @ 2005-07-19 16:14 UTC (permalink / raw)
  To: Lei Ming, gcc-help

[-- Attachment #1: Type: text/plain, Size: 1781 bytes --]


> I wonder what's the purpose of "subl $25, %eax"? If the compiler knows that
> the whole loop is useless, since we don't really use the result, why not just
> eliminate this loop and simply return zero? If it choose to execute the loop,
> why it is the number 25 instead of other number? Why not 42? :-)

GCC hasn't removed empty loops in the past and I think this topic has had long
discussions already.  It's probably not worth starting a new one, on whether
it shall or shall not do it.  But reading Ian's reply, it seems this is now
different on mainline.  Good thing.

GCC is able to do optimization of the style:
    for (i = 0; i < 100; i++) do_something();
to
    for (i = 0; i < 100; i += 2) { do_something(); do_something(); }
to reduce the overhead of the loop.  (There's a name for it, but I don't
remember.)  In this example, it always does 2 loop iterations at a time,
and only needs to 'loop' 50 times.  In your example, it makes 25 steps at
a time and therefore increments the iterator by 25 on each cycle.  42 won't
trivially work in the same way, because it is not a divisor of 100.

> I'm using GCC 3.2.3:

That's an old version.  I suggest you upgrade to 3.4.4 (or to 4.0.x if you
want) unless you have reasons not to do that.  I'm not even sure whether bug
reports for 3.2.x version and below are welcome anyway, given that's pretty old.

This is the output of 3.4.4 on my i686-pc-linux-gnu (-O3 -funroll-all-loops)

main:   pushl   %ebp
        xorl    %eax, %eax
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        subl    $16, %esp
        .p2align 4,,7
.L5:    addl    $10, %eax
        cmpl    $99, %eax
        jle     .L5
        leave
        xorl    %eax, %eax
        ret

It takes steps of 10 here.

Cheers,
jlh

[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 256 bytes --]

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

end of thread, other threads:[~2005-07-19 16:14 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-19  2:51 GCC Unrolling Simple Loop Generates Rubbish Code? Lei Ming
2005-07-19  4:00 ` Ian Lance Taylor
2005-07-19 16:14 ` jlh

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