The following code is producing false results with -O2 optimization (-O1 and O3 are correct): ------- #include <stdio.h> #define BLOCK_SIZE 100000 int main() { int i; float block_f[BLOCK_SIZE]; int d_phase = 0; int d_phase_inc = 0x100000; for (i = 0; i < BLOCK_SIZE; i++){ block_f[i] = (float)(d_phase); d_phase += d_phase_inc; } printf ("%x %x\n", (int)block_f[1695], (int)block_f[1696]); return 0; } ----- With -O2, the loop is run only 0x6a0 times, instead of 0x186a0 times. gcc is from openSUSE 11.0 (4.3.1 20080507 (prerelease) [gcc-4_3-branch revision 135036] (SUSE Linux)), but fc9 is most probably affected as well. Failing code is a very simplified test case from gnuradio (http://www.ruby-forum.com/topic/156807)
This works for me as far as I can see (you didn't specify the expected output, and certainly if the loop doesn't run as often as you want you may print uninitialized memory). Anyway, if it doesn't work then it is because d_phase overflows and so invokes undefined behavior.
The expected output is quite clear - 69f00000 6a000000 - but output is 69f00000 0. The loop should run 100000 times, as i does not overflow. d_phase does overflow after 2048 steps, but this should not influence the loop. with -O2, gcc seems to do the following: - d_phase is the same as i*0x100000 - the block should run 0x186a0 times - (0x186a0 * 0x100000) & 0xffffffff = 0x6a000000 - break when d_phase reaches 0x6a000000 (1696 increment steps) with -O3 and -O1, d_phase and i get their own variables there should be at least a warning
>The loop should run 100000 times, as i does not overflow. i does not overflow but d_phase_inc does ...
As I said - it works for me (i686, gcc (Debian 4.3.1-8) 4.3.1). Still the overflow invokes undefined behavior and thus _can_ affect the loop.
>The loop should run 100000 times, as i does not overflow. i does not overflow but d_phase does ... 2046 7ff00000 2047 80000000 That is an overflow. So is: 4094 fff00000 4095 0
So is there any possibility to flag a variable to be expected to overflow and "wrap around"? I think there is a lot of code in the wild assuming the loop to run 100000 times and d_phase to overflow all the time, becoming negative.
Subject: Re: gcc creating wrong code with -O2 Just make it unsigned since unsigned overflow is always defined.
You can use -fwrapv.