Hi,
by code reading I became aware that libgcc can call count_leading_zeros
in certain cases which can give undefined results. This happens on
signed int128 -> float or double conversions, when the int128 is in the range
INT64_MAX+1 to UINT64_MAX.
On x86_64, there is (more or less by chance) no visible effect, because a
"BSR esi, esi" instruction is used, which leaves the esi register unchanged,
thus the result is only off by one, but that may change at any time.
This precautionary patch uses COUNT_LEADING_ZEROS_0 to check
what the result of count_leading_zeros(0) will be, and avoids that call
if the result is not W_TYPE_SIZE.
Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
Is it OK for trunk?
Thanks
Bernd.
2016-10-27 Bernd Edlinger <bernd.edlin...@hotmail.de>
PR libgcc/78067
* libgcc2.c (__floatdisf, __floatdidf): Avoid undefined results from
count_leading_zeros.
Index: libgcc2.c
===================================================================
--- libgcc2.c (revision 241400)
+++ libgcc2.c (working copy)
@@ -1643,6 +1643,11 @@
hi = -(UWtype) hi;
UWtype count, shift;
+#if !defined (COUNT_LEADING_ZEROS_0) || COUNT_LEADING_ZEROS_0 != W_TYPE_SIZE
+ if (hi == 0)
+ count = W_TYPE_SIZE;
+ else
+#endif
count_leading_zeros (count, hi);
/* No leading bits means u == minimum. */