GCC 4.8.4 4.9.2 nifti_swap_2bytes optimization bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux