diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2015-10-18 22:30:43 -0400 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2015-10-19 09:08:44 -0400 |
commit | 3ec400f5ce53ea1a56d283bc6bf59e75762df058 (patch) | |
tree | 4279c06eaa939e9fcf5c2bec3e752333a104b59d /pp.c | |
parent | ced634a413de975cd30ac5f5d08a1c43d2b402b3 (diff) | |
download | perl-3ec400f5ce53ea1a56d283bc6bf59e75762df058.tar.gz |
perl #126396 IRIX longdouble infinity issues
In IRIX longdouble (which uses the double-double format, bigendian)
multiplying with infinity introduces garbage bytes to the second double
of the double-double.
This garbage, in turn, seems to tickle another bug in long doubles,
in comparing infinities, where these garbage bytes errorneously matter
when they should not.
Workaround: zero these garbage bytes in multiplication.
The garbage bytes seem to appear only the multiplication, as far as
t/op/infnan.t can detect.
Even though we could place the multiplication result to a temporary NV
variable (for easier infiniteness inspection) for all the platforms and
depend on optimizer doing away with the temporary, let's be conservative.
Diffstat (limited to 'pp.c')
-rw-r--r-- | pp.c | 10 |
1 files changed, 10 insertions, 0 deletions
@@ -1394,7 +1394,17 @@ PP(pp_multiply) NV right = SvNV_nomg(svr); NV left = SvNV_nomg(svl); (void)POPs; +#if defined(__sgi) && defined(USE_LONG_DOUBLE) && LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN && NVSIZE == 16 + { + NV result = left * right; + if (Perl_isinf(result)) { + Zero((U8*)&result + 8, 8, U8); + } + SETn( result ); + } +#else SETn( left * right ); +#endif RETURN; } } |