On Sat, Oct 29, 2016 at 05:47:54AM +0000, Bernd Edlinger wrote: > On 10/28/16 16:05, Bernd Edlinger wrote: > > On 10/27/16 22:23, Joseph Myers wrote: > >> On Thu, 27 Oct 2016, Bernd Edlinger wrote: > >> > >>> 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. > >> > >> I'd expect testcases added to the testsuite that exercise this case at > >> runtime, if not already present. > >> > > > > Yes, thanks. I somehow expected there were already test cases, > > somewhere, but now when you ask that, I begin to doubt as well... > > > > I will try to add an asm("int 3") and see if that gets hit at all. > > > > The breakpoint got hit only once, in the libgo testsuite: runtime/pprof. > > I see there are some int to float conversion tests at > gcc.dg/torture/fp-int-convert*.c, where it is easy to add a > test case that hits the breakpoint too. > > However the test case does not fail before the patch, > it is just slightly undefined behavior, that is not > causing problems (at least for x86_64). > > Find attached a new patch with test case.
These new test cases look like they are going to be out of exponent range for _Float16 - so the testcases will fail for a target which tests either of: gcc.dg/torture/fp-int-convert-float16.c gcc.dg/torture/fp-int-convert-float16-timode.c Should they have an M_OK1 check? Thanks, James > > > Boot-strapped 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. > > testsuite: > 2016-10-27 Bernd Edlinger <bernd.edlin...@hotmail.de> > > PR libgcc/78067 > * gcc.dg/torture/fp-int-convert.h: Add more conversion tests. > > > 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. */ > Index: gcc/testsuite/gcc.dg/torture/fp-int-convert.h > =================================================================== > --- gcc/testsuite/gcc.dg/torture/fp-int-convert.h (revision 241647) > +++ gcc/testsuite/gcc.dg/torture/fp-int-convert.h (working copy) > @@ -53,6 +53,8 @@ do { > \ > TEST_I_F_VAL (U, F, HVAL1U (P, U), P_OK (P, U)); \ > TEST_I_F_VAL (U, F, HVAL1U (P, U) + 1, P_OK (P, U)); \ > TEST_I_F_VAL (U, F, HVAL1U (P, U) - 1, P_OK (P, U)); \ > + TEST_I_F_VAL (I, F, WVAL0S (I), 1); \ > + TEST_I_F_VAL (I, F, -WVAL0S (I), 1); \ > } while (0) > > #define P_OK(P, T) ((P) >= sizeof(T) * CHAR_BIT) > @@ -74,6 +76,7 @@ do { > \ > ? (S)1 \ > : (((S)1 << (sizeof(S) * CHAR_BIT - 2)) \ > + ((S)3 << (sizeof(S) * CHAR_BIT - 2 - P)))) > +#define WVAL0S(S) (S)((S)1 << (sizeof(S) * CHAR_BIT / 2 - 1)) > > #define TEST_I_F_VAL(IT, FT, VAL, PREC_OK) \ > do { \