Example code: void flash_wait_ready(volatile unsigned *vaddr) { while (*vaddr != *vaddr) ; } Using gcc 3.3 (tested with arm-elf and i686-pc-linux-gnu), the loop in the example above is incorrectly removed by the optimizer when using -O. Correct code is generated using -O2, -O3 and -Os. Here is the -O case: > gcc -S -o - -O tmp.c .file "tmp.c" .text .globl flash_wait_ready .type flash_wait_ready, @function flash_wait_ready: pushl %ebp movl %esp, %ebp popl %ebp ret .size flash_wait_ready, .-flash_wait_ready .ident "GCC: (GNU) 3.3" > It's a regression from GCC 3.2.3 which generates correct code with -O. [I know the code looks funny, but as the function name indicates I'm waiting for a flash memory to finish. When the flash is busy, two consecutive read accesses will not read the same value.] /Tobias
Info from Andrew Pinski: Please file a bug report but I still see it on the mainline (). Also Here is a workaround: void flash_wait_ready(volatile unsigned *vaddr) { while(1) { unsigned temp = *vaddr; if (temp != *vaddr) break; } } Thanks, Andrew Pinski
Confirmed, a regression in 3.3 and mainline w.r.t. 3.2. Here's another work-around: --------------------------- void flash_wait_ready(unsigned * volatile vaddr) { while (*vaddr != *vaddr) ; } --------------------------- I must admit that I think that this one is wrong, though, as it makes the _pointer_ volatile, not the object pointed to. W.
Fixing.
Subject: Bug 11381 CVSROOT: /cvs/gcc Module name: gcc Changes by: ebotcazou@gcc.gnu.org 2003-07-03 07:30:03 Modified files: gcc : ChangeLog simplify-rtx.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg: i386-volatile-1.c Log message: PR optimization/11381 * simplify-rtx.c (simplify_relational_operation): Check that two equal operands have no side-effects before simplifying the comparison. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.308&r2=2.309 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/simplify-rtx.c.diff?cvsroot=gcc&r1=1.144&r2=1.145 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.2829&r2=1.2830 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-volatile-1.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
Subject: Bug 11381 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-3_3-branch Changes by: ebotcazou@gcc.gnu.org 2003-07-03 07:38:29 Modified files: gcc : ChangeLog simplify-rtx.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.dg: i386-volatile-1.c Log message: PR optimization/11381 * simplify-rtx.c (simplify_relational_operation): Check that two equal operands have no side-effects before simplifying the comparison. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.16114.2.631&r2=1.16114.2.632 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/simplify-rtx.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.126.4.2&r2=1.126.4.3 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=1.2261.2.214&r2=1.2261.2.215 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.dg/i386-volatile-1.c.diff?cvsroot=gcc&only_with_tag=gcc-3_3-branch&r1=NONE&r2=1.1.2.1
See http://gcc.gnu.org/ml/gcc-patches/2003-07/msg00175.html
I've tested the fix on arm-elf by applying your patch to simplify-rtx.c to the gcc-3.3 source. I then compiled my original code and it works perfectly. Thanks a lot for the quick response. I'm impressed!