On 27 November 2014 at 12:16, Ola Liljedahl <ola.liljedahl@linaro.org> wrote:
Thanks Maxim,

Yes I should do that. I also intend to make the code used to reproduce
the problem smaller.

One of my worries was that GCC considered the loop without side
effects (ignoring the inline assembler in odp_spin()) and thus removed
the loop (including the usage of the uninitialized variable). But that
does not seem to be the case.

-- Ola


Shouldn't preprocessor (cpp) show what really happens?

Maxim.

 
On 27 November 2014 at 08:58, Maxim Kuvyrkov <maxim.kuvyrkov@linaro.org> wrote:
> 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)
>
>
>
>

_______________________________________________
lng-odp mailing list
lng-odp@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/lng-odp