Re: gcc: loop do not terminate

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



On 2013-05-13 18:20:05, LANGLOIS Olivier PIS -EXT wrote:
> Date: Mon, 13 May 2013 18:20:05 +0000
> From: LANGLOIS Olivier PIS -EXT <olivier.pis.langlois@xxxxxxxxxxxxxxxxxxxx>
> To: "General Discussion about Arch Linux (arch-general@xxxxxxxxxxxxx)"
>  <arch-general@xxxxxxxxxxxxx>
> Subject: [arch-general] gcc: loop do not terminate
> 
> I have just been hit by something:
> 
> lano1106@hpmini ~/dev/gcc-test $ g++ --version
> g++ (GCC) 4.8.0 20130502 (prerelease)
> Copyright (C) 2013 Free Software Foundation, Inc.
> This is free software; see the source for copying conditions.  There is NO
> warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> 
> lano1106@hpmini ~/dev/gcc-test $ g++ -O2 -o test1 test1.cpp test1_init.cpp
> lano1106@hpmini ~/dev/gcc-test $ ./test1
> item 0
>  a: 1
> lano1106@hpmini ~/dev/gcc-test $ g++ -O1 -o test1 test1.cpp test1_init.cpp
> lano1106@hpmini ~/dev/gcc-test $ ./test1
> item 0
>  a: 1

  I have checked the disassemble of -O1 result,
in fact, the for-loop seems optimized out. Not increasment operation(++i),
and not jump to the loop begining:

        for( int i = 0; i < arr[0].numelem; ++i )
  4005df:       8b 14 24                mov    (%rsp),%edx
  4005e2:       85 d2                   test   %edx,%edx
  4005e4:       7e 1b                   jle    400601 <main+0x41>
        {
                printf( "item %d/%d: a = %d\n",
                        i,
                        arr[0].numelem,
                        122 + arr[0].item[i].a
                                );
  4005e6:       8b 44 24 04             mov    0x4(%rsp),%eax
  4005ea:       8d 48 7a                lea    0x7a(%rax),%ecx
  4005ed:       be 00 00 00 00          mov    $0x0,%esi
  4005f2:       bf b4 06 40 00          mov    $0x4006b4,%edi
  4005f7:       b8 00 00 00 00          mov    $0x0,%eax
  4005fc:       e8 9f fe ff ff          callq  4004a0 <printf@plt>
        }

        return 0;
}
  400601:       b8 00 00 00 00          mov    $0x0,%eax
  400606:       48 81 c4 48 01 00 00    add    $0x148,%rsp
  40060d:       c3                      retq   
  40060e:       66 90                   xchg   %ax,%ax

any one can help to explain it?


> lano1106@hpmini ~/dev/gcc-test $ g++ -O0 -o test1 test1.cpp test1_init.cpp
> lano1106@hpmini ~/dev/gcc-test $ ./test1
> item 0
>  a: 1
> item 1
>  a: 2
> lano1106@hpmini ~/dev/gcc-test $ cat test1.h
> 
> struct A
> {
>         int a;
>         int b;
>         int c;
> };
> 
> struct B
> {
>         int numelem;
>         /*
>          * Old C trick to define a dynamically sizable array just by allocating
>          * sizeof(B) + (numelem-1)*sizeof(A) memory.
>          */
>         A   item[1];
> };
> 
> void initArr(B *p);
> 
> lano1106@hpmini ~/dev/gcc-test $ cat test1_init.cpp
> #include "test1.h"
> 
> void initArr(B *p)
> {
>         p->numelem = 2;
>         p->item[0].a = 1;
>         p->item[1].a = 2;
> }
> 
> lano1106@hpmini ~/dev/gcc-test $ cat test1.cpp
> /*
>  * Author: Olivier Langlois <olivier@xxxxxxxxxxxxxx>
>  *
>  * Purpose: Small test to highlight gcc optimization bug
>  */
> 
> #include <stdio.h>
> #include <string.h>
> #include "test1.h"
> 
> /*
>  * Create a B array with the intent of only using the first item.
>  * The 19 other items sole purpose is to create a buffer large enough
>  * to accomodate A array needs.
>  */
> #define MAXBLEN 20
> 
> int main(int argc, char *argv[])
> {
>         B arr[MAXBLEN];
>         memset(arr,0,sizeof(arr));
> 
>         initArr(arr);
> 
>         for( int i = 0; i < arr[0].numelem; ++i )
>         {
>                 printf( "item %d\n"
>                         " a: %d\n",
>                         i,
>                         arr[0].item[i].a);
>         }
> 
>         return 0;
> }
> 
> From gcc website, this is not a bug:
> 
> Loops do not terminate
> 
>     This is often caused by out-of-bound array accesses or by signed integer overflow which both result in undefined behavior according to the ISO C standard. For example
> 
>         int
>         SATD (int* diff, int use_hadamard)
>         {
>           int k, satd = 0, m[16], dd, d[16];
>           ...
>             for (dd=d[k=0]; k<16; dd=d[++k])
>               satd += (dd < 0 ? -dd : dd);
> 
>     accesses d[16] before the loop is exited with the k<16 check. This causes the compiler to optimize away the exit test because the new value of k must be in the range [0, 15] according to ISO C.
> 
>     GCC starting with version 4.8 has a new option -fno-aggressive-loop-optimizations that may help here. If it does, then this is a clear sign that your code is not conforming to ISO C and it is not a GCC bug.
> 
> I am surprised that I didn't hit the problem before but I am seriously considering using '-fno-aggressive-loop-optimizations' in my own makepkg.conf. I just want to test others feeling on this discovery to see if it wouldn't be a good idea to make the switch standard in Arch...
> 
> 
> ________________________________
> CONFIDENTIALITY : This e-mail and any attachments are confidential and may be privileged. If you are not a named recipient, please notify the sender immediately and do not disclose the contents to another person, use it for any purpose or store or copy the information in any medium.



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux