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 <[email protected]>
> To: "General Discussion about Arch Linux ([email protected])"
> <[email protected]>
> 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 <[email protected]>
> *
> * 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.