diff options
author | Neil Fortner <nfortne2@hdfgroup.org> | 2013-09-27 15:35:44 (GMT) |
---|---|---|
committer | Neil Fortner <nfortne2@hdfgroup.org> | 2013-09-27 15:35:44 (GMT) |
commit | cd90900d88d2baaf4ef3b4ad6aa30af64a4581cd (patch) | |
tree | f2ce465f1da740f4b6cb9a5711d051b49473ad6a | |
parent | b3b29e4485dbdf4eef82f71da8f5b6a5e2509b8e (diff) | |
download | hdf5-cd90900d88d2baaf4ef3b4ad6aa30af64a4581cd.zip hdf5-cd90900d88d2baaf4ef3b4ad6aa30af64a4581cd.tar.gz hdf5-cd90900d88d2baaf4ef3b4ad6aa30af64a4581cd.tar.bz2 |
[svn-r24209] Port r24171 from trunk to 1.8 branch.
Tested: jam, koala, ostrich, platypus (h5committest)
Log from r24171:
Purpose: Fix problem with gcc 4.8
Description:
With optimization enabled, gcc 4.8 inserts garbage into the padding bytes of
floating point types when assigning from a literal constant. This caused
problems when H5detect.c scanned the bits in floating point types to determine
their properties.
Modified H5detect.c to scan for padding before further analyzing the type, and
to ignore all information in the padding areas. Also removed code that
temporarily disabled optimization.
Tested: jam, koala, ostrich, platypus (h5committest)
-rw-r--r-- | config/gnu-flags | 5 | ||||
-rw-r--r-- | release_docs/RELEASE.txt | 4 | ||||
-rw-r--r-- | src/CMakeLists.txt | 7 | ||||
-rw-r--r-- | src/H5detect.c | 215 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/Makefile.in | 24 |
6 files changed, 128 insertions, 128 deletions
diff --git a/config/gnu-flags b/config/gnu-flags index 57fc23a..b965bf0 100644 --- a/config/gnu-flags +++ b/config/gnu-flags @@ -156,11 +156,6 @@ case "$cc_vendor-$cc_version" in gcc-3.*) PROD_CFLAGS="-O3" ;; - gcc-4.8.*) - # temp patch: when GCC 4.8.x is used for Linux, dt_arith fails if -O* - # is used. Remove any -O* flags. (AKC HDFFV-8500) - PROD_CFLAGS="`echo $PROD_CFLAGS | sed -e 's/-O[0-3]*//'`" - ;; gcc-4.*) PROD_CFLAGS="-O3" ;; diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 81576f0..2b120fd 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -102,7 +102,9 @@ Bug Fixes since HDF5-1.8.11 Configuration ------------- - - None + - Modified H5detect.c to scan floating point types for padding bits before + analyzing the type further. This should fix problems with gcc 4.8 + (NAF - 2013/09/19 - HDFFV-8523/HDFFV-8500) Library ------- diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7439977..64d5e87 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -613,13 +613,8 @@ INCLUDE_DIRECTORIES (${CMAKE_BINARY_DIR}) # Setup the H5Detect utility which generates H5Tinit with platform # specific type checks inside #----------------------------------------------------------------------------- -IF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) - SET (LOCAL_OPT_FLAG "-O0") -ELSE (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) - SET (LOCAL_OPT_FLAG " ") -ENDIF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) ADD_EXECUTABLE (H5detect ${HDF5_SRC_DIR}/H5detect.c) -TARGET_C_PROPERTIES (H5detect ${LOCAL_OPT_FLAG} " ") +TARGET_C_PROPERTIES (H5detect " " " ") IF (MSVC) TARGET_LINK_LIBRARIES (H5detect "ws2_32.lib") ENDIF (MSVC) diff --git a/src/H5detect.c b/src/H5detect.c index caed569..be661ea 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -118,10 +118,12 @@ static volatile int nd_g = 0, na_g = 0; static void print_results(int nd, detected_t *d, int na, malign_t *m); static void iprint(detected_t *); -static int byte_cmp(int, const void *, const void *); -static int bit_cmp(int, int *, volatile void *, volatile void *); +static int byte_cmp(int, const void *, const void *, const unsigned char *); +static int bit_cmp(int, int *, volatile void *, volatile void *, + const unsigned char *); static void fix_order(int, int, int *, const char **); -static int imp_bit(int, int *, volatile void *, volatile void *); +static int imp_bit(int, int *, volatile void *, volatile void *, + const unsigned char *); static unsigned long find_bias(int, int, int *, void *); static void precision (detected_t*); static void print_header(void); @@ -298,71 +300,88 @@ precision (detected_t *d) * *------------------------------------------------------------------------- */ -#define DETECT_F(TYPE,VAR,INFO) { \ - volatile TYPE _v1, _v2, _v3; \ - unsigned char _buf1[sizeof(TYPE)], _buf3[sizeof(TYPE)]; \ - int _i, _j, _last = (-1); \ - char *_mesg; \ - \ - HDmemset(&INFO, 0, sizeof(INFO)); \ - INFO.varname = #VAR; \ - INFO.size = sizeof(TYPE); \ - \ - /* Completely initialize temporary variables, in case the bits used in */ \ - /* the type take less space than the number of bits used to store the type */ \ - HDmemset(&_v3, 0, sizeof(TYPE)); \ - HDmemset(&_v2, 0, sizeof(TYPE)); \ - HDmemset(&_v1, 0, sizeof(TYPE)); \ - \ - /* Byte Order */ \ - for(_i = 0, _v1 = 0.0, _v2 = 1.0; _i < (int)sizeof(TYPE); _i++) { \ - _v3 = _v1; \ - _v1 += _v2; \ - _v2 /= 256.0; \ - HDmemcpy(_buf1, (const void *)&_v1, sizeof(TYPE)); \ - HDmemcpy(_buf3, (const void *)&_v3, sizeof(TYPE)); \ - _j = byte_cmp(sizeof(TYPE), &_buf3, &_buf1); \ - if(_j >= 0) { \ - INFO.perm[_i] = _j; \ - _last = _i; \ - } \ - } \ - fix_order(sizeof(TYPE), _last, INFO.perm, (const char**)&_mesg); \ +#define DETECT_F(TYPE,VAR,INFO) { \ + volatile TYPE _v1, _v2, _v3; \ + unsigned char _buf1[sizeof(TYPE)], _buf3[sizeof(TYPE)]; \ + unsigned char _pad_mask[sizeof(TYPE)]; \ + unsigned char _byte_mask; \ + int _i, _j, _last = (-1); \ + char *_mesg; \ \ - if(!HDstrcmp(_mesg, "VAX")) \ - INFO.is_vax = TRUE; \ - \ - /* Implicit mantissa bit */ \ - _v1 = 0.5; \ - _v2 = 1.0; \ - INFO.imp = imp_bit (sizeof(TYPE), INFO.perm, &_v1, &_v2); \ - \ - /* Sign bit */ \ - _v1 = 1.0; \ - _v2 = -1.0; \ - INFO.sign = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2); \ - \ - /* Mantissa */ \ - INFO.mpos = 0; \ - \ - _v1 = 1.0; \ - _v2 = 1.5; \ - INFO.msize = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2); \ - INFO.msize += 1 + (INFO.imp?0:1) - INFO.mpos; \ - \ - /* Exponent */ \ - INFO.epos = INFO.mpos + INFO.msize; \ - \ - INFO.esize = INFO.sign - INFO.epos; \ - \ - _v1 = 1.0; \ - INFO.bias = find_bias (INFO.epos, INFO.esize, INFO.perm, &_v1); \ - precision (&(INFO)); \ - ALIGNMENT(TYPE, INFO); \ - if(!HDstrcmp(INFO.varname, "FLOAT") || !HDstrcmp(INFO.varname, "DOUBLE") || \ - !HDstrcmp(INFO.varname, "LDOUBLE")) { \ - COMP_ALIGNMENT(TYPE,INFO.comp_align); \ - } \ + HDmemset(&INFO, 0, sizeof(INFO)); \ + INFO.varname = #VAR; \ + INFO.size = sizeof(TYPE); \ + \ + /* Initialize padding mask */ \ + HDmemset(_pad_mask, 0, sizeof(_pad_mask)); \ + \ + /* Padding bits. Set a variable to 4.0, then flip each bit and see if \ + * the modified variable is equal ("==") to the original. Build a \ + * padding bitmask to indicate which bits in the type are padding (i.e. \ + * have no effect on the value and should be ignored by subsequent \ + * steps). This is necessary because padding bits can change arbitrarily \ + * and interfere with detection of the various properties below unless we \ + * know to ignore them. */ \ + _v1 = 4.0; \ + HDmemcpy(_buf1, (const void *)&_v1, sizeof(TYPE)); \ + for(_i = 0; _i < (int)sizeof(TYPE); _i++) \ + for(_byte_mask = (unsigned char)1; _byte_mask; _byte_mask <<= 1) { \ + _buf1[_i] ^= _byte_mask; \ + HDmemcpy((void *)&_v2, (const void *)_buf1, sizeof(TYPE)); \ + if(_v1 != _v2) \ + _pad_mask[_i] |= _byte_mask; \ + _buf1[_i] ^= _byte_mask; \ + } /* enf for */ \ + \ + /* Byte Order */ \ + for(_i = 0, _v1 = 0.0, _v2 = 1.0; _i < (int)sizeof(TYPE); _i++) { \ + _v3 = _v1; \ + _v1 += _v2; \ + _v2 /= 256.0; \ + HDmemcpy(_buf1, (const void *)&_v1, sizeof(TYPE)); \ + HDmemcpy(_buf3, (const void *)&_v3, sizeof(TYPE)); \ + _j = byte_cmp(sizeof(TYPE), _buf3, _buf1, _pad_mask); \ + if(_j >= 0) { \ + INFO.perm[_i] = _j; \ + _last = _i; \ + } \ + } \ + fix_order(sizeof(TYPE), _last, INFO.perm, (const char**)&_mesg); \ + \ + if(!HDstrcmp(_mesg, "VAX")) \ + INFO.is_vax = TRUE; \ + \ + /* Implicit mantissa bit */ \ + _v1 = 0.5; \ + _v2 = 1.0; \ + INFO.imp = imp_bit (sizeof(TYPE), INFO.perm, &_v1, &_v2, _pad_mask); \ + \ + /* Sign bit */ \ + _v1 = 1.0; \ + _v2 = -1.0; \ + INFO.sign = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2, _pad_mask); \ + \ + /* Mantissa */ \ + INFO.mpos = 0; \ + \ + _v1 = 1.0; \ + _v2 = 1.5; \ + INFO.msize = bit_cmp (sizeof(TYPE), INFO.perm, &_v1, &_v2, _pad_mask); \ + INFO.msize += 1 + (INFO.imp?0:1) - INFO.mpos; \ + \ + /* Exponent */ \ + INFO.epos = INFO.mpos + INFO.msize; \ + \ + INFO.esize = INFO.sign - INFO.epos; \ + \ + _v1 = 1.0; \ + INFO.bias = find_bias (INFO.epos, INFO.esize, INFO.perm, &_v1); \ + precision (&(INFO)); \ + ALIGNMENT(TYPE, INFO); \ + if(!HDstrcmp(INFO.varname, "FLOAT") || !HDstrcmp(INFO.varname, "DOUBLE") || \ + !HDstrcmp(INFO.varname, "LDOUBLE")) { \ + COMP_ALIGNMENT(TYPE,INFO.comp_align); \ + } \ } @@ -887,7 +906,8 @@ iprint(detected_t *d) * * Purpose: Compares two chunks of memory A and B and returns the * byte index into those arrays of the first byte that - * differs between A and B. + * differs between A and B. Ignores differences where the + * corresponding bit in pad_mask is set to 0. * * Return: Success: Index of differing byte. * @@ -902,13 +922,16 @@ iprint(detected_t *d) *------------------------------------------------------------------------- */ static int -byte_cmp(int n, const void *_a, const void *_b) +byte_cmp(int n, const void *_a, const void *_b, const unsigned char *pad_mask) { - int i; - const unsigned char *a = (const unsigned char *) _a; - const unsigned char *b = (const unsigned char *) _b; + int i; + const unsigned char *a = (const unsigned char *) _a; + const unsigned char *b = (const unsigned char *) _b; + + for(i = 0; i < n; i++) + if((a[i] & pad_mask[i]) != (b[i] & pad_mask[i])) + return i; - for (i = 0; i < n; i++) if (a[i] != b[i]) return i; return -1; } @@ -919,7 +942,8 @@ byte_cmp(int n, const void *_a, const void *_b) * Purpose: Compares two bit vectors and returns the index for the * first bit that differs between the two vectors. The * size of the vector is NBYTES. PERM is a mapping from - * actual order to little endian. + * actual order to little endian. Ignores differences where + * the corresponding bit in pad_mask is set to 0. * * Return: Success: Index of first differing bit. * @@ -934,22 +958,24 @@ byte_cmp(int n, const void *_a, const void *_b) *------------------------------------------------------------------------- */ static int -bit_cmp(int nbytes, int *perm, volatile void *_a, volatile void *_b) +bit_cmp(int nbytes, int *perm, volatile void *_a, volatile void *_b, + const unsigned char *pad_mask) { - int i, j; - volatile unsigned char *a = (volatile unsigned char *) _a; - volatile unsigned char *b = (volatile unsigned char *) _b; - unsigned char aa, bb; + int i, j; + volatile unsigned char *a = (volatile unsigned char *) _a; + volatile unsigned char *b = (volatile unsigned char *) _b; + unsigned char aa, bb; for (i = 0; i < nbytes; i++) { - HDassert(perm[i] < nbytes); - if ((aa = a[perm[i]]) != (bb = b[perm[i]])) { - for (j = 0; j < 8; j++, aa >>= 1, bb >>= 1) { - if ((aa & 1) != (bb & 1)) return i * 8 + j; - } - fprintf(stderr, "INTERNAL ERROR"); - HDabort(); - } + HDassert(perm[i] < nbytes); + if ((aa = a[perm[i]] & pad_mask[perm[i]]) + != (bb = b[perm[i]] & pad_mask[perm[i]])) { + for (j = 0; j < 8; j++, aa >>= 1, bb >>= 1) { + if ((aa & 1) != (bb & 1)) return i * 8 + j; + } + fprintf(stderr, "INTERNAL ERROR"); + HDabort(); + } } return -1; } @@ -1058,18 +1084,19 @@ fix_order(int n, int last, int *perm, const char **mesg) *------------------------------------------------------------------------- */ static int -imp_bit(int n, int *perm, volatile void *_a, volatile void *_b) +imp_bit(int n, int *perm, volatile void *_a, volatile void *_b, + const unsigned char *pad_mask) { - volatile unsigned char *a = (volatile unsigned char *) _a; - volatile unsigned char *b = (volatile unsigned char *) _b; - int changed, major, minor; - int msmb; /*most significant mantissa bit */ + volatile unsigned char *a = (volatile unsigned char *) _a; + volatile unsigned char *b = (volatile unsigned char *) _b; + int changed, major, minor; + int msmb; /*most significant mantissa bit */ /* * Look for the least significant bit that has changed between - * A and B. This is the least significant bit of the exponent. + * A and B. This is the least significant bit of the exponent. */ - changed = bit_cmp(n, perm, a, b); + changed = bit_cmp(n, perm, a, b, pad_mask); HDassert(changed >= 0); /* diff --git a/src/Makefile.am b/src/Makefile.am index f94c811..c26eba7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,7 +27,6 @@ include $(top_srcdir)/config/lt_vers.am # a long time to compile it with any optimization on. H5detect is used # to generate H5Tinit.c once. So, optimization is not critical. noinst_PROGRAMS = H5detect H5make_libsettings -H5detect_CFLAGS = $(AM_CFLAGS) -g -O0 # Our main target, the HDF5 library lib_LTLIBRARIES=libhdf5.la diff --git a/src/Makefile.in b/src/Makefile.in index 062ee13..476ea03 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -177,11 +177,8 @@ libhdf5_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(libhdf5_la_LDFLAGS) $(LDFLAGS) -o $@ PROGRAMS = $(noinst_PROGRAMS) H5detect_SOURCES = H5detect.c -H5detect_OBJECTS = H5detect-H5detect.$(OBJEXT) +H5detect_OBJECTS = H5detect.$(OBJEXT) H5detect_LDADD = $(LDADD) -H5detect_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(H5detect_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ H5make_libsettings_SOURCES = H5make_libsettings.c H5make_libsettings_OBJECTS = H5make_libsettings.$(OBJEXT) H5make_libsettings_LDADD = $(LDADD) @@ -519,7 +516,6 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog LT_VERS_INTERFACE = 8 LT_VERS_REVISION = 1 LT_VERS_AGE = 0 -H5detect_CFLAGS = $(AM_CFLAGS) -g -O0 # Our main target, the HDF5 library lib_LTLIBRARIES = libhdf5.la @@ -734,7 +730,7 @@ clean-noinstPROGRAMS: rm -f $$list H5detect$(EXEEXT): $(H5detect_OBJECTS) $(H5detect_DEPENDENCIES) $(EXTRA_H5detect_DEPENDENCIES) @rm -f H5detect$(EXEEXT) - $(AM_V_CCLD)$(H5detect_LINK) $(H5detect_OBJECTS) $(H5detect_LDADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(H5detect_OBJECTS) $(H5detect_LDADD) $(LIBS) H5make_libsettings$(EXEEXT): $(H5make_libsettings_OBJECTS) $(H5make_libsettings_DEPENDENCIES) $(EXTRA_H5make_libsettings_DEPENDENCIES) @rm -f H5make_libsettings$(EXEEXT) $(AM_V_CCLD)$(LINK) $(H5make_libsettings_OBJECTS) $(H5make_libsettings_LDADD) $(LIBS) @@ -981,7 +977,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ztrans.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5checksum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5dbg.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5detect-H5detect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5detect.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5lib_settings.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5make_libsettings.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5system.Plo@am__quote@ @@ -1009,20 +1005,6 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< -H5detect-H5detect.o: H5detect.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -MT H5detect-H5detect.o -MD -MP -MF $(DEPDIR)/H5detect-H5detect.Tpo -c -o H5detect-H5detect.o `test -f 'H5detect.c' || echo '$(srcdir)/'`H5detect.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/H5detect-H5detect.Tpo $(DEPDIR)/H5detect-H5detect.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='H5detect.c' object='H5detect-H5detect.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -c -o H5detect-H5detect.o `test -f 'H5detect.c' || echo '$(srcdir)/'`H5detect.c - -H5detect-H5detect.obj: H5detect.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -MT H5detect-H5detect.obj -MD -MP -MF $(DEPDIR)/H5detect-H5detect.Tpo -c -o H5detect-H5detect.obj `if test -f 'H5detect.c'; then $(CYGPATH_W) 'H5detect.c'; else $(CYGPATH_W) '$(srcdir)/H5detect.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/H5detect-H5detect.Tpo $(DEPDIR)/H5detect-H5detect.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='H5detect.c' object='H5detect-H5detect.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(H5detect_CFLAGS) $(CFLAGS) -c -o H5detect-H5detect.obj `if test -f 'H5detect.c'; then $(CYGPATH_W) 'H5detect.c'; else $(CYGPATH_W) '$(srcdir)/H5detect.c'; fi` - mostlyclean-libtool: -rm -f *.lo |