Optimizer problem with repeated loops over memory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I have extracted the following section of code from some boot code that tests DRAM. As a result this code cannot be run without causing a segmentation fault, but the problem it illustrates occurs in the real DRAM test and can be seen it the code disassembly.

This bug has been seen in gcc 4.1.2 and gcc 4.2.1

The code has two loops, which compile correctly when no optimization, or -O1 are used, but the second loop becomes infinite if -Os or -O2 is used.

The code is:

#include <stdio.h>

int main()
{
        volatile unsigned int *addr;
        unsigned int      readback;
        int      i;

        addr = 0;
        for (i = 0; i < 16; i++) *(addr++) = 0;
        for (i = 0; i < 16; i++) {
                printf("\n reads %d, 0x%08X", i, addr);
                readback = *(--addr);
        }
        return 0;
}


The object dump produced by 'gcc test.c' looks correct:

08048384 <main>:
 8048384:       8d 4c 24 04             lea    0x4(%esp),%ecx
 8048388:       83 e4 f0                and    $0xfffffff0,%esp
 804838b:       ff 71 fc                pushl  0xfffffffc(%ecx)
 804838e:       55                      push   %ebp
 804838f:       89 e5                   mov    %esp,%ebp
 8048391:       51                      push   %ecx
 8048392:       83 ec 24                sub    $0x24,%esp
 8048395:       c7 45 f0 00 00 00 00    movl   $0x0,0xfffffff0(%ebp)
 804839c:       c7 45 f8 00 00 00 00    movl   $0x0,0xfffffff8(%ebp)
 80483a3:       eb 11                   jmp    80483b6 <main+0x32>
 80483a5:       8b 45 f0                mov    0xfffffff0(%ebp),%eax
 80483a8:       c7 00 00 00 00 00       movl   $0x0,(%eax)
 80483ae:       83 45 f0 04             addl   $0x4,0xfffffff0(%ebp)
 80483b2:       83 45 f8 01             addl   $0x1,0xfffffff8(%ebp)
 80483b6:       83 7d f8 0f             cmpl   $0xf,0xfffffff8(%ebp)
 80483ba:       7e e9                   jle    80483a5 <main+0x21>
 80483bc:       c7 45 f8 00 00 00 00    movl   $0x0,0xfffffff8(%ebp)
 80483c3:       eb 2a                   jmp    80483ef <main+0x6b>
 80483c5:       8b 45 f0                mov    0xfffffff0(%ebp),%eax
 80483c8:       89 44 24 08             mov    %eax,0x8(%esp)
 80483cc:       8b 45 f8                mov    0xfffffff8(%ebp),%eax
 80483cf:       89 44 24 04             mov    %eax,0x4(%esp)
 80483d3:       c7 04 24 e0 84 04 08    movl   $0x80484e0,(%esp)
 80483da:       e8 b9 fe ff ff          call   8048298 <printf@plt>
 80483df:       83 6d f0 04             subl   $0x4,0xfffffff0(%ebp)
 80483e3:       8b 45 f0                mov    0xfffffff0(%ebp),%eax
 80483e6:       8b 00                   mov    (%eax),%eax
 80483e8:       89 45 f4                mov    %eax,0xfffffff4(%ebp)
 80483eb:       83 45 f8 01             addl   $0x1,0xfffffff8(%ebp)
 80483ef:       83 7d f8 0f             cmpl   $0xf,0xfffffff8(%ebp)
 80483f3:       7e d0                   jle    80483c5 <main+0x41>
 80483f5:       b8 00 00 00 00          mov    $0x0,%eax
 80483fa:       83 c4 24                add    $0x24,%esp
 80483fd:       59                      pop    %ecx
 80483fe:       5d                      pop    %ebp
 80483ff:       8d 61 fc                lea    0xfffffffc(%ecx),%esp
 8048402:       c3                      ret
 8048403:       90                      nop

The object dump produced by 'gcc -Os test.c' seems to have lost the condition on the second loop so continues indefinitely :

08048384 <main>:
 8048384:       8d 4c 24 04             lea    0x4(%esp),%ecx
 8048388:       83 e4 f0                and    $0xfffffff0,%esp
 804838b:       ff 71 fc                pushl  0xfffffffc(%ecx)
 804838e:       55                      push   %ebp
 804838f:       89 e5                   mov    %esp,%ebp
 8048391:       56                      push   %esi
 8048392:       53                      push   %ebx
 8048393:       31 db                   xor    %ebx,%ebx
 8048395:       51                      push   %ecx
 8048396:       83 ec 0c                sub    $0xc,%esp
 8048399:       c7 03 00 00 00 00       movl   $0x0,(%ebx)
 804839f:       83 c3 04                add    $0x4,%ebx
 80483a2:       83 fb 40                cmp    $0x40,%ebx
 80483a5:       75 f2                   jne    8048399 <main+0x15>
 80483a7:       31 f6                   xor    %esi,%esi
 80483a9:       50                      push   %eax
 80483aa:       53                      push   %ebx
 80483ab:       83 eb 04                sub    $0x4,%ebx
 80483ae:       56                      push   %esi
 80483af:       46                      inc    %esi
 80483b0:       68 a0 84 04 08          push   $0x80484a0
 80483b5:       e8 de fe ff ff          call   8048298 <printf@plt>
 80483ba:       8b 03                   mov    (%ebx),%eax
 80483bc:       83 c4 10                add    $0x10,%esp
 80483bf:       eb e8                   jmp    80483a9 <main+0x25>
 80483c1:       90                      nop
 80483c2:       90                      nop
 80483c3:       90                      nop

In this case the second loop no longer has a condition so repeats indefinitely.

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux