From be3a33155025d6ef2d57533b60b96c888ab314a6 Mon Sep 17 00:00:00 2001 From: Neil Fortner Date: Thu, 19 Sep 2013 13:57:41 -0500 Subject: [svn-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) --- config/gnu-flags | 5 -- release_docs/RELEASE.txt | 3 + src/CMakeLists.txt | 7 +- src/H5detect.c | 215 ++++++++++++++++++++++++++--------------------- src/Makefile.am | 1 - src/Makefile.in | 24 +----- 6 files changed, 128 insertions(+), 127 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 92a6ce4..cd694a6 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -677,6 +677,9 @@ Bug Fixes since HDF5-1.8.0 release Configuration ------------- + - 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) - Fixed Makefile issue in which "-Wl," was not properly specified prior to -rpath when building parallel fortran libraries with an Intel compiler. (MAM - 2012/03/26) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8e7a3bf..718a41f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -773,13 +773,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 2d7640e..f63a36e 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 f215b74..b31a9ae 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -182,11 +182,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) @@ -524,7 +521,6 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog LT_VERS_INTERFACE = 6 LT_VERS_REVISION = 154 LT_VERS_AGE = 0 -H5detect_CFLAGS = $(AM_CFLAGS) -g -O0 # Our main target, the HDF5 library lib_LTLIBRARIES = libhdf5.la @@ -744,7 +740,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) @@ -1013,7 +1009,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@ @@ -1041,20 +1037,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 -- cgit v0.12