summaryrefslogtreecommitdiff
path: root/pp.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2015-10-18 22:30:43 -0400
committerJarkko Hietaniemi <jhi@iki.fi>2015-10-19 09:08:44 -0400
commit3ec400f5ce53ea1a56d283bc6bf59e75762df058 (patch)
tree4279c06eaa939e9fcf5c2bec3e752333a104b59d /pp.c
parentced634a413de975cd30ac5f5d08a1c43d2b402b3 (diff)
downloadperl-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.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/pp.c b/pp.c
index 6e9995af2a..b084d4949c 100644
--- a/pp.c
+++ b/pp.c
@@ -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;
}
}