0005-Provide-a-C-version-of-iszero-that-does-not-use-__MA.patch 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. From 45970aa26d1af87b016ef95b4b35c566aeb6e841 Mon Sep 17 00:00:00 2001
  2. From: "Gabriel F. T. Gomes" <gftg@linux.vnet.ibm.com>
  3. Date: Tue, 22 Aug 2017 16:34:42 -0300
  4. Subject: [PATCH] Provide a C++ version of iszero that does not use __MATH_TG
  5. (bug 21930)
  6. When signaling nans are enabled (with -fsignaling-nans), the C++ version
  7. of iszero uses the fpclassify macro, which is defined with __MATH_TG.
  8. However, when support for float128 is available, __MATH_TG uses the
  9. builtin __builtin_types_compatible_p, which is only available in C mode.
  10. This patch refactors the C++ version of iszero so that it uses function
  11. overloading to select between the floating-point types, instead of
  12. relying on fpclassify and __MATH_TG.
  13. Tested for powerpc64le, s390x, x86_64, and with build-many-glibcs.py.
  14. [BZ #21930]
  15. * math/math.h [defined __cplusplus && defined __SUPPORT_SNAN__]
  16. (iszero): New C++ implementation that does not use
  17. fpclassify/__MATH_TG/__builtin_types_compatible_p, when
  18. signaling nans are enabled, since __builtin_types_compatible_p
  19. is a C-only feature.
  20. * math/test-math-iszero.cc: When __HAVE_DISTINCT_FLOAT128 is
  21. defined, include ieee754_float128.h for access to the union and
  22. member ieee854_float128.ieee.
  23. [__HAVE_DISTINCT_FLOAT128] (do_test): Call check_float128.
  24. [__HAVE_DISTINCT_FLOAT128] (check_float128): New function.
  25. * sysdeps/powerpc/powerpc64le/Makefile [subdir == math]
  26. (CXXFLAGS-test-math-iszero.cc): Add -mfloat128 to the build
  27. options of test-math-zero on powerpc64le.
  28. (cherry picked from commit 42496114ec0eb7d6d039d05d4262e109951c600c)
  29. [Romain rebase on glibc 2.26]
  30. Signed-off-by: Romain Naour <romain.naour@gmail.com>
  31. ---
  32. math/math.h | 33 +++++++++++++--
  33. math/test-math-iszero.cc | 79 ++++++++++++++++++++++++++++++++++++
  34. sysdeps/powerpc/powerpc64le/Makefile | 3 +-
  35. 3 files changed, 110 insertions(+), 5 deletions(-)
  36. diff --git a/math/math.h b/math/math.h
  37. index 60dfa31..7c0fc6d 100644
  38. --- a/math/math.h
  39. +++ b/math/math.h
  40. @@ -513,15 +513,40 @@ inline int issignaling (_Float128 __val) { return __issignalingf128 (__val); }
  41. # endif
  42. # else /* __cplusplus */
  43. extern "C++" {
  44. +# ifdef __SUPPORT_SNAN__
  45. +inline int
  46. +iszero (float __val)
  47. +{
  48. + return __fpclassifyf (__val) == FP_ZERO;
  49. +}
  50. +inline int
  51. +iszero (double __val)
  52. +{
  53. + return __fpclassify (__val) == FP_ZERO;
  54. +}
  55. +inline int
  56. +iszero (long double __val)
  57. +{
  58. +# ifdef __NO_LONG_DOUBLE_MATH
  59. + return __fpclassify (__val) == FP_ZERO;
  60. +# else
  61. + return __fpclassifyl (__val) == FP_ZERO;
  62. +# endif
  63. +}
  64. +# if __HAVE_DISTINCT_FLOAT128
  65. +inline int
  66. +iszero (_Float128 __val)
  67. +{
  68. + return __fpclassifyf128 (__val) == FP_ZERO;
  69. +}
  70. +# endif
  71. +# else
  72. template <class __T> inline bool
  73. iszero (__T __val)
  74. {
  75. -# ifdef __SUPPORT_SNAN__
  76. - return fpclassify (__val) == FP_ZERO;
  77. -# else
  78. return __val == 0;
  79. -# endif
  80. }
  81. +# endif
  82. } /* extern C++ */
  83. # endif /* __cplusplus */
  84. #endif /* Use IEC_60559_BFP_EXT. */
  85. diff --git a/math/test-math-iszero.cc b/math/test-math-iszero.cc
  86. index 027e972..5c07261 100644
  87. --- a/math/test-math-iszero.cc
  88. +++ b/math/test-math-iszero.cc
  89. @@ -22,6 +22,13 @@
  90. #include <limits>
  91. +/* Support for _Float128 in std::numeric_limits is limited.
  92. + Include ieee754_float128.h and use the bitfields in the union
  93. + ieee854_float128.ieee_nan to build corner-case inputs. */
  94. +#if __HAVE_DISTINCT_FLOAT128
  95. +# include <ieee754_float128.h>
  96. +#endif
  97. +
  98. static bool errors;
  99. static void
  100. @@ -72,12 +79,84 @@ check_type ()
  101. std::numeric_limits<T>::has_denorm == std::denorm_absent);
  102. }
  103. +#if __HAVE_DISTINCT_FLOAT128
  104. +static void
  105. +check_float128 ()
  106. +{
  107. + ieee854_float128 q;
  108. +
  109. + q.d = 0.0Q;
  110. + CHECK (iszero (q.d), 1);
  111. + q.d = -0.0Q;
  112. + CHECK (iszero (q.d), 1);
  113. + q.d = 1.0Q;
  114. + CHECK (iszero (q.d), 0);
  115. + q.d = -1.0Q;
  116. + CHECK (iszero (q.d), 0);
  117. +
  118. + /* Normal min. */
  119. + q.ieee.negative = 0;
  120. + q.ieee.exponent = 0x0001;
  121. + q.ieee.mantissa0 = 0x0000;
  122. + q.ieee.mantissa1 = 0x00000000;
  123. + q.ieee.mantissa2 = 0x00000000;
  124. + q.ieee.mantissa3 = 0x00000000;
  125. + CHECK (iszero (q.d), 0);
  126. + q.ieee.negative = 1;
  127. + CHECK (iszero (q.d), 0);
  128. +
  129. + /* Normal max. */
  130. + q.ieee.negative = 0;
  131. + q.ieee.exponent = 0x7FFE;
  132. + q.ieee.mantissa0 = 0xFFFF;
  133. + q.ieee.mantissa1 = 0xFFFFFFFF;
  134. + q.ieee.mantissa2 = 0xFFFFFFFF;
  135. + q.ieee.mantissa3 = 0xFFFFFFFF;
  136. + CHECK (iszero (q.d), 0);
  137. + q.ieee.negative = 1;
  138. + CHECK (iszero (q.d), 0);
  139. +
  140. + /* Infinity. */
  141. + q.ieee.negative = 0;
  142. + q.ieee.exponent = 0x7FFF;
  143. + q.ieee.mantissa0 = 0x0000;
  144. + q.ieee.mantissa1 = 0x00000000;
  145. + q.ieee.mantissa2 = 0x00000000;
  146. + q.ieee.mantissa3 = 0x00000000;
  147. + CHECK (iszero (q.d), 0);
  148. +
  149. + /* Quiet NaN. */
  150. + q.ieee_nan.quiet_nan = 1;
  151. + q.ieee_nan.mantissa0 = 0x0000;
  152. + CHECK (iszero (q.d), 0);
  153. +
  154. + /* Signaling NaN. */
  155. + q.ieee_nan.quiet_nan = 0;
  156. + q.ieee_nan.mantissa0 = 0x4000;
  157. + CHECK (iszero (q.d), 0);
  158. +
  159. + /* Denormal min. */
  160. + q.ieee.negative = 0;
  161. + q.ieee.exponent = 0x0000;
  162. + q.ieee.mantissa0 = 0x0000;
  163. + q.ieee.mantissa1 = 0x00000000;
  164. + q.ieee.mantissa2 = 0x00000000;
  165. + q.ieee.mantissa3 = 0x00000001;
  166. + CHECK (iszero (q.d), 0);
  167. + q.ieee.negative = 1;
  168. + CHECK (iszero (q.d), 0);
  169. +}
  170. +#endif
  171. +
  172. static int
  173. do_test (void)
  174. {
  175. check_type<float> ();
  176. check_type<double> ();
  177. check_type<long double> ();
  178. +#if __HAVE_DISTINCT_FLOAT128
  179. + check_float128 ();
  180. +#endif
  181. return errors;
  182. }
  183. diff --git a/sysdeps/powerpc/powerpc64le/Makefile b/sysdeps/powerpc/powerpc64le/Makefile
  184. index 19adbfa..dea2290 100644
  185. --- a/sysdeps/powerpc/powerpc64le/Makefile
  186. +++ b/sysdeps/powerpc/powerpc64le/Makefile
  187. @@ -17,7 +17,8 @@ $(foreach suf,$(all-object-suffixes),$(objpfx)test-float128%$(suf)): CFLAGS += -
  188. $(foreach suf,$(all-object-suffixes),$(objpfx)test-ifloat128%$(suf)): CFLAGS += -mfloat128
  189. CFLAGS-libm-test-support-float128.c += -mfloat128
  190. CFLAGS-test-math-issignaling.cc += -mfloat128
  191. -$(objpfx)test-float128% $(objpfx)test-ifloat128%: \
  192. +CFLAGS-test-math-iszero.cc += -mfloat128
  193. +$(objpfx)test-float128% $(objpfx)test-ifloat128% $(objpfx)test-math-iszero: \
  194. gnulib-tests += $(f128-loader-link)
  195. endif
  196. --
  197. 2.9.5