Hi, I believe I have encountered a bug in the optimization at least in versions 4.8.4 and 4.9.2. The problem is not present in version 4.6.3. The attached complete example code can be used to reproduce the error (my system is Ubuntu 12.04). This code is crucial in medical image processing where the NIfTI-1 file format is commonly used. The respective function that is optimized incorrectly by most recent C/C++ compilers of GCC was copied from the NIfTI-1 C library and is used by many medical image processing tools. It is responsible for swapping the bytes if necessary when the image data was written on a system with differing endianness. The problem is only present with optimization level >1 (i.e., -O2 or -O3), e.g., gcc swap.c -o swap -O2 -v The verbose output is enclosed as well. Running the program with the argument 768, for example, should produce the output 3. However, with the optimization enabled, the input argument is not modified. > ./swap 768 3 Andreas
#include <stdlib.h> #include <stdio.h> typedef struct { unsigned char a, b; } twobytes; void nifti_swap_2bytes( int n , void *ar ) /* 2 bytes at a time */ { register int ii ; register twobytes *tb = (twobytes *)ar ; register unsigned char tt ; for( ii=0 ; ii < n ; ii++ ){ tt = tb[ii].a ; tb[ii].a = tb[ii].b ; tb[ii].b = tt ; } return ; } int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "usage: %s <short>\n", argv[0]); exit(1); } short value = atoi(argv[1]); nifti_swap_2bytes(1, &value); fprintf(stdout, "%d\n", value); exit(0); }
Using built-in specs. COLLECT_GCC=/homes/as12312/opt/bin/gcc-4.9 COLLECT_LTO_WRAPPER=/vol/biomedic/users/as12312/libexec/gcc/x86_64-unknown-linux-gnu/4.9.2/lto-wrapper Target: x86_64-unknown-linux-gnu Configured with: /vol/biomedic/users/as12312/src/gcc-4.9.2/configure --prefix=/vol/biomedic/users/as12312 --program-suffix=-4.9 --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --disable-multilib --with-system-zlib --enable-languages=c,c++,fortran,go,objc,obj-c++ Thread model: posix gcc version 4.9.2 (GCC) COLLECT_GCC_OPTIONS='-o' 'swap' '-O2' '-v' '-mtune=generic' '-march=x86-64' /vol/biomedic/users/as12312/libexec/gcc/x86_64-unknown-linux-gnu/4.9.2/cc1 -quiet -v -imultiarch x86_64-linux-gnu swap.c -quiet -dumpbase swap.c -mtune=generic -march=x86-64 -auxbase swap -O2 -version -o /tmp/ccg53hCO.s GNU C (GCC) version 4.9.2 (x86_64-unknown-linux-gnu) compiled by GNU C version 4.9.2, GMP version 5.0.2, MPFR version 3.1.0-p3, MPC version 0.9 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" ignoring nonexistent directory "/vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../x86_64-unknown-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/include /usr/local/include /vol/biomedic/users/as12312/include /vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/include-fixed /usr/include/x86_64-linux-gnu /usr/include End of search list. GNU C (GCC) version 4.9.2 (x86_64-unknown-linux-gnu) compiled by GNU C version 4.9.2, GMP version 5.0.2, MPFR version 3.1.0-p3, MPC version 0.9 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: b0721d2a5a73b48b78d84c8a00358d2c COLLECT_GCC_OPTIONS='-o' 'swap' '-O2' '-v' '-mtune=generic' '-march=x86-64' as -v --64 -o /tmp/cc1aQhM3.o /tmp/ccg53hCO.s GNU assembler version 2.22 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.22 COMPILER_PATH=/vol/biomedic/users/as12312/libexec/gcc/x86_64-unknown-linux-gnu/4.9.2/:/vol/biomedic/users/as12312/libexec/gcc/x86_64-unknown-linux-gnu/4.9.2/:/vol/biomedic/users/as12312/libexec/gcc/x86_64-unknown-linux-gnu/:/vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/:/vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/ LIBRARY_PATH=/vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/:/vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../lib64/:/lib/x86_64-linux-gnu/:/lib/../lib64/:/usr/lib/x86_64-linux-gnu/:/vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-o' 'swap' '-O2' '-v' '-mtune=generic' '-march=x86-64' /vol/biomedic/users/as12312/libexec/gcc/x86_64-unknown-linux-gnu/4.9.2/collect2 -plugin /vol/biomedic/users/as12312/libexec/gcc/x86_64-unknown-linux-gnu/4.9.2/liblto_plugin.so -plugin-opt=/vol/biomedic/users/as12312/libexec/gcc/x86_64-unknown-linux-gnu/4.9.2/lto-wrapper -plugin-opt=-fresolution=/tmp/ccLLWzYi.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o swap /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o /vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/crtbegin.o -L/vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2 -L/vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/../../.. /tmp/cc1aQhM3.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /vol/biomedic/users/as12312/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/crtend.o /usr/lib/x86_64-linux-gnu/crtn.o