On 12 November 2012 22:19, Mickey Iluz mickey.iluz@orcam.com wrote:
Hi,
I've encountered a case where gcc produces a broken program: a branch that should never be taken is taken, and wrong values are written to memory (and printed out). The code is fairly ordinary and small. It can be seen here: http://pastebin.com/0Hspz8mw
This happens when -funroll-loops flag is used in conjunction with -O2 or -O3. It doesn't seem to happen when it is used with -O1.
Another few things that influences the program flow from from incorrect to correct run (gives expected outpus) are:
Adding/removing printf's inside the inner loop
Changing the order of the expressions in the "if" clause. i.e. from this:
if ((y < mu) || (y >= H - md) || (x < ml) || (x >= W - mr))
to this:
if ((x < ml) || (y >= H - md) || (y < mu) || (x >= W - mr))
Assigning ml inside f() to the same value (3) it's getting from the function arguments.
All of these shouldn't change how the program behaves but it does.
I compiled this with two different compilers/environments:
- g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, running on 3.2.1-42-linaro-lt-mx6 (native compilation on the ARM board)
Compilation command: g++ -march=armv7-a -mfpu=neon -mfloat-abi=hard -mtune=cortex-a9 -O3 -std=c++0x -funroll-loops -o test_bug_sa_loops_linaro test_bug.cxx
- arm-fsl-linux-gnueabi-g++ (Freescale MAD -- Linaro 2011.07 -- Built at 2011/08/10 09:20) 4.6.2 20110630 (prerelease) Running on a freescale LTIB built linux (3.0.15-1359-g1b64ead)
Compilation command: arm-fsl-linux-gnueabi-g++ -march=armv7-a -mfpu=neon -mfloat-abi=hard -mtune=cortex-a9 -O3 -std=c++0x -funroll-loops -o test_bug_sa_loops test_bug.cxx
In all the variations I tried it seems that -funroll-loops is critical for this problem to appear.
I'd be glad to hear some comments on this.
Hi Mickey. I can reproduce the problem and can't see anything wrong with the code itself. I changed things about to remove the printfs and instead dump the image to the console inside main(). What I see is the whole of the image being correct except for the first column from rows 3 onwards also being set instead of being clear.
The fault is cleared with GCC 4.7. I haven't looked further to track down the fix. Could you upgrade to 4.7?
-- Michael