Hi Ola,
I can confirm this problem with latest linaro-4.9-branch build. However, this is target-independent problem (reproducible on, at least, x86 and aarch64), so it is best to be tracked and addressed via upstream bugzilla.
Would you submit a PR on http://gcc.gnu.org/bugzilla ?
Thank you,
-- Maxim Kuvyrkov www.linaro.org
On Nov 25, 2014, at 1:34 AM, Pinski, Andrew Andrew.Pinski@caviumnetworks.com wrote:
Forwarding this message to the linaro toolchain list instead. I am not the person who should be supporting the Linaro ODP project with GCC questiosn; the toolchain team inside Linaro should be instead.
Thanks, Andrew Pinski
From: Ola Liljedahl ola.liljedahl@linaro.org Sent: Monday, November 24, 2014 2:31 PM To: lng-odp@lists.linaro.org; Pinski, Andrew Subject: strange behavior in GCC for use of uninitialized variables
Consider the following code fragment (from real life):
#include <stdint.h>
typedef volatile uint32_t odp_atomic_u32_t;
static inline uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *ptr) { return __sync_fetch_and_add(ptr, 1); }
static inline void odp_spin(void) { #ifdef __SSE2__ __asm__ __volatile__ ("pause"); #else __asm__ __volatile__ ("rep; nop"); #endif }
typedef struct { int count; odp_atomic_u32_t bar; } odp_barrier_t;
void odp_barrier_wait(odp_barrier_t *barrier) { uint32_t count; int wasless;
// wasless = barrier->bar < barrier->count; <<<lost on git add -p __atomic_thread_fence(__ATOMIC_SEQ_CST); count = odp_atomic_fetch_inc_u32(&barrier->bar);
if (count == 2*barrier->count-1) { barrier->bar = 0; } else { while ((barrier->bar < barrier->count) == wasless) odp_spin(); } __atomic_thread_fence(__ATOMIC_SEQ_CST);
}
While fixing and cleaning up this code, the indicated line that initializes 'wasless' was dropped (because it reappears in a later patch in the patch set after the odp_atomic_fetch_inc call). To my surprise, GCC did not complain when compiling this file (using -O2 -Wall). But it does complain when compiling with -O0 -Wall. With some investigation, it seems like GCC understands that if a statement does not have any side effects so it can optimize away everything, including the usage of the uninitialized variable and thus also the corresponding warning.
olli@macmini:~/hacking/gcc-wunit$ gcc -O2 -Wall -c odp_barrier.c olli@macmini:~/hacking/gcc-wunit$ gcc -O0 -Wall -c odp_barrier.c odp_barrier.c: In function ‘odp_barrier_wait’: odp_barrier.c:42:9: warning: ‘wasless’ may be used uninitialized in this function [-Wmaybe-uninitialized] while ((barrier->bar < barrier->count) == was less)