diff options
-rw-r--r-- | config/cmake/ConfigureChecks.cmake | 5 | ||||
-rw-r--r-- | config/cmake/ConversionTests.c | 24 | ||||
-rw-r--r-- | config/cmake/H5pubconf.h.in | 3 | ||||
-rw-r--r-- | configure.ac | 24 | ||||
-rw-r--r-- | test/dt_arith.c | 81 |
5 files changed, 128 insertions, 9 deletions
diff --git a/config/cmake/ConfigureChecks.cmake b/config/cmake/ConfigureChecks.cmake index 459346e..c1abeed 100644 --- a/config/cmake/ConfigureChecks.cmake +++ b/config/cmake/ConfigureChecks.cmake @@ -247,6 +247,11 @@ H5ConversionTests (${HDF_PREFIX}_LDOUBLE_TO_LLONG_ACCURATE "Checking IF correctl # H5ConversionTests (${HDF_PREFIX}_LLONG_TO_LDOUBLE_CORRECT "Checking IF correctly converting (unsigned) long long to long double values") # ---------------------------------------------------------------------- +# Set the flag to indicate that the machine can accurately convert +# some long double values +# +H5ConversionTests (${HDF_PREFIX}_DISABLE_SOME_LDOUBLE_CONV "Checking IF the cpu is power9 and cannot correctly converting long double values") +# ---------------------------------------------------------------------- # Check if pointer alignments are enforced # H5ConversionTests (${HDF_PREFIX}_NO_ALIGNMENT_RESTRICTIONS "Checking IF alignment restrictions are strictly enforced") diff --git a/config/cmake/ConversionTests.c b/config/cmake/ConversionTests.c index c2748b2..6d597a0 100644 --- a/config/cmake/ConversionTests.c +++ b/config/cmake/ConversionTests.c @@ -287,3 +287,27 @@ main () #endif +#ifdef H5_DISABLE_SOME_LDOUBLE_CONV_TEST + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int HDF_NO_UBSAN main(void) +{ + FILE *fp; + char cpu[64]; + + fp = popen("uname -m", "r"); + + fgets(cpu, sizeof(cpu)-1, fp); + + pclose(fp); + + if(strncmp(cpu, "ppc64le", 7) == 0) + return 0; + + return 1; +} + +#endif diff --git a/config/cmake/H5pubconf.h.in b/config/cmake/H5pubconf.h.in index 4edaff0..871a78d 100644 --- a/config/cmake/H5pubconf.h.in +++ b/config/cmake/H5pubconf.h.in @@ -460,6 +460,9 @@ with special algorithm. */ #cmakedefine H5_LONG_TO_LDOUBLE_SPECIAL @H5_LONG_TO_LDOUBLE_SPECIAL@ +/* Define if your system is power6 and cannot convert some long double values. */ +#cmakedefine H5_DISABLE_SOME_LDOUBLE_CONV @H5_DISABLE_SOME_LDOUBLE_CONV@ + /* Define to the sub-directory where libtool stores uninstalled libraries. */ #cmakedefine H5_LT_OBJDIR @H5_LT_OBJDIR@ diff --git a/configure.ac b/configure.ac index 6b591ae..4f37bd4 100644 --- a/configure.ac +++ b/configure.ac @@ -2970,6 +2970,30 @@ else fi ## ---------------------------------------------------------------------- +## Set the flag to indicate that the machine is IBM ppc64le and cannot +## accurately convert some long double values. +## +AC_MSG_CHECKING([if the system is IBM ppc64le and cannot correctly convert some long double values]) + +TEST_SRC="`(echo \"#define H5_DISABLE_SOME_LDOUBLE_CONV_TEST 1\"; cat $srcdir/config/cmake/ConversionTests.c)`" + +if test ${ac_cv_sizeof_long_double} = 0; then + hdf5_cv_disable_some_ldouble_conv=${hdf5_cv_disable_some_ldouble_conv=no} +else + AC_CACHE_VAL([hdf5_cv_disable_some_ldouble_conv], + [AC_RUN_IFELSE([AC_LANG_SOURCE([$TEST_SRC])], + [hdf5_cv_disable_some_ldouble_conv=yes], [hdf5_cv_disable_some_ldouble_conv=no],[])]) +fi + +if test ${hdf5_cv_disable_some_ldouble_conv} = "yes"; then + AC_DEFINE([DISABLE_SOME_LDOUBLE_CONV], [1], + [Define if your system is IBM ppc64le and cannot convert some long double values correctly.]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +## ---------------------------------------------------------------------- ## Set some variables for general configuration information to be saved ## and installed with the libraries (used to generate libhdf5.settings). ## diff --git a/test/dt_arith.c b/test/dt_arith.c index c7f2986..2729ba1 100644 --- a/test/dt_arith.c +++ b/test/dt_arith.c @@ -4883,7 +4883,24 @@ run_fp_tests(const char *name) #if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE!=0 nerrors += test_conv_flt_1(name, TEST_DENORM, H5T_NATIVE_FLOAT, H5T_NATIVE_LDOUBLE); nerrors += test_conv_flt_1(name, TEST_DENORM, H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE); +#ifndef H5_DISABLE_SOME_LDOUBLE_CONV nerrors += test_conv_flt_1(name, TEST_DENORM, H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT); +#else + { + char str[256]; /*string */ + + HDsnprintf(str, sizeof(str), "Testing %s denormalized %s -> %s conversions", + name, "long double", "float"); + printf("%-70s", str); + SKIPPED(); +#if H5_SIZEOF_LONG_DOUBLE!=0 + HDputs(" Test skipped due to the conversion problem on IBM ppc64le cpu."); +#else + HDputs(" Test skipped due to disabled long double."); +#endif + } +#endif + nerrors += test_conv_flt_1(name, TEST_DENORM, H5T_NATIVE_LDOUBLE, H5T_NATIVE_DOUBLE); #endif @@ -4893,8 +4910,24 @@ run_fp_tests(const char *name) #if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE && H5_SIZEOF_LONG_DOUBLE!=0 nerrors += test_conv_flt_1(name, TEST_SPECIAL, H5T_NATIVE_FLOAT, H5T_NATIVE_LDOUBLE); nerrors += test_conv_flt_1(name, TEST_SPECIAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_LDOUBLE); +#ifndef H5_DISABLE_SOME_LDOUBLE_CONV nerrors += test_conv_flt_1(name, TEST_SPECIAL, H5T_NATIVE_LDOUBLE, H5T_NATIVE_FLOAT); nerrors += test_conv_flt_1(name, TEST_SPECIAL, H5T_NATIVE_LDOUBLE, H5T_NATIVE_DOUBLE); +#else + { + char str[256]; /*string */ + + HDsnprintf(str, sizeof(str), "Testing %s special %s -> %s conversions", + name, "long double", "float or double"); + printf("%-70s", str); + SKIPPED(); +#if H5_SIZEOF_LONG_DOUBLE!=0 + HDputs(" Test skipped due to the conversion problem on IBM ppc64le cpu."); +#else + HDputs(" Test skipped due to disabled long double."); +#endif + } +#endif #endif done: @@ -4963,7 +4996,7 @@ run_int_fp_conv(const char *name) nerrors += test_conv_int_fp(name, TEST_NORMAL, H5T_NATIVE_INT, H5T_NATIVE_LDOUBLE); nerrors += test_conv_int_fp(name, TEST_NORMAL, H5T_NATIVE_UINT, H5T_NATIVE_LDOUBLE); #if H5_SIZEOF_LONG!=H5_SIZEOF_INT -#ifndef H5_LONG_TO_LDOUBLE_SPECIAL +#if !defined(H5_LONG_TO_LDOUBLE_SPECIAL) && !defined(H5_DISABLE_SOME_LDOUBLE_CONV) nerrors += test_conv_int_fp(name, TEST_NORMAL, H5T_NATIVE_LONG, H5T_NATIVE_LDOUBLE); nerrors += test_conv_int_fp(name, TEST_NORMAL, H5T_NATIVE_ULONG, H5T_NATIVE_LDOUBLE); #else @@ -5077,16 +5110,46 @@ run_fp_int_conv(const char *name) #endif #if H5_SIZEOF_LONG_DOUBLE!=H5_SIZEOF_DOUBLE - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SCHAR); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UCHAR); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SHORT); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_USHORT); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_INT); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UINT); + if(test_values != TEST_SPECIAL) { + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SCHAR); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UCHAR); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SHORT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_USHORT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_INT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UINT); + } else { +#ifndef H5_DISABLE_SOME_LDOUBLE_CONV + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SCHAR); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UCHAR); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_SHORT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_USHORT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_INT); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_UINT); +#else + char str[256]; /*string */ + + HDsnprintf(str, sizeof(str), "Testing %s special %s -> %s conversions", + name, "long double", "signed and unsigned char, short, int, long"); + printf("%-70s", str); + SKIPPED(); +#if H5_SIZEOF_LONG_DOUBLE!=0 + HDputs(" Test skipped due to the conversion problem on IBM ppc64le cpu."); +#else + HDputs(" Test skipped due to disabled long double."); +#endif +#endif + } #if H5_SIZEOF_LONG!=H5_SIZEOF_INT && H5_SIZEOF_LONG_DOUBLE!=0 #ifndef H5_LDOUBLE_TO_LONG_SPECIAL - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LONG); - nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_ULONG); + if(test_values != TEST_SPECIAL && test_values != TEST_NORMAL) { + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_ULONG); + } else { +#ifndef H5_DISABLE_SOME_LDOUBLE_CONV + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_LONG); + nerrors += test_conv_int_fp(name, test_values, H5T_NATIVE_LDOUBLE, H5T_NATIVE_ULONG); +#endif + } #else { char str[256]; /*string */ |