This is a follow-up on a discussion about OpenMPI that started at
http://www.open-mpi.org/community/lists/users/2015/06/27039.php
and continued at https://github.com/open-mpi/ompi/pull/625

The attached test program does not produce correct results with gcc
4.9.2 and gcc 5.1.0 with -O1 or greater (gcc 4.8.7 is safe)

At first glance, it seems gcc is not aware a wrapper can be added to
posix_memalign and hence posix_memalign can have some side effects
such as updating user global variables.


A workaround is to declare the global variable as volatile.

The expected output of this test program is :
global = 0
changed !
global = 1


here are the full outputs with gcc 4.9.2 and 5.1.0 and from O0 to O3

$ gcc --version ; for i in 0 1 2 3 ; do echo ; echo opt = O$i ; gcc -o
test.O$i -Wno-deprecated-declarations -O$i test.c ; ./test.O$i ; done
gcc (GCC) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


opt = O0
global = 0
changed !
global = 1

opt = O1
global = 0
global = 1

opt = O2
global = 0
global = 0

opt = O3
global = 0
global = 0


$ gcc --version ; for i in 0 1 2 3 ; do echo ; echo opt = O$i ; gcc -o
test.O$i -Wno-deprecated-declarations -O$i test.c ; ./test.O$i ; done
gcc (GCC) 5.1.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


opt = O0
global = 0
changed !
global = 1

opt = O1
global = 0
global = 0

opt = O2
global = 0
global = 0

opt = O3
global = 0
global = 0


please note the different behaviour with O1 between gcc 4.9.2 and gcc 5.1.0


Could you please comment on this issue ?
- is this a bug ?
- is this a "feature" ? (e.g. a known to be aggressive optimization
that explicitly requires the global variable is declared as volatile)


Thanks and regards,

Gilles
#include <stdlib.h>
#include <malloc.h>

int global;

void *hook (size_t alignment, size_t size, const void *caller);


void *hook (size_t alignment, size_t size, const void *caller) {
    global = 1;
}

int main (int argc, char *argv) {
    void * c;
    global = 0;
    printf ("global = %d\n", global);
    __memalign_hook = hook;
    if (0 == global) {
        posix_memalign(&c, 0x1000, 1);
        if (0 != global)
            printf ("changed !\n");
        printf ("global = %d\n", global);
    }
    return 0;
}

Reply via email to