shithub: mc

Download patch

ref: 7c4d2abbe14d3d0e9d2f5872e0964677c5dc783d
parent: c8ace93eceb07e2415ce785e47efe3ee643855d5
author: S. Gilles <sgilles@math.umd.edu>
date: Wed Mar 21 12:17:45 EDT 2018

Correct sign handling in fma32 when one of x, y is NaN

--- a/lib/math/fpmath-fma-impl.myr
+++ b/lib/math/fpmath-fma-impl.myr
@@ -9,10 +9,24 @@
 const exp_mask64 : uint64 = 0x7ff << 52
 
 pkglocal const fma32 = {x : flt32, y : flt32, z : flt32
+	var xn, yn
+	(xn, _, _) = std.flt32explode(x)
+	(yn, _, _) = std.flt32explode(y)
 	var xd : flt64 = flt64fromflt32(x)
 	var yd : flt64 = flt64fromflt32(y)
 	var zd : flt64 = flt64fromflt32(z)
 	var prod : flt64 = xd * yd
+	var pn, pe, ps
+	(pn, pe, ps) = std.flt64explode(prod)
+	if pe == -1023
+		pe = -1022
+	;;
+	if pn != (xn != yn)
+		/* In case of NaNs, sign might not have been preserved */
+		pn = (xn != yn)
+		prod = std.flt64assem(pn, pe, ps)
+	;;
+
 	var r : flt64 = prod + zd
 
 	var zn, ze, zs
@@ -19,11 +33,6 @@
 	(zn, ze, zs) = std.flt32explode(z)
 	if ze == -127
 		ze = -126
-	;;
-	var pn, pe, ps
-	(pn, pe, ps) = std.flt64explode(prod)
-	if pe == -1023
-		pe = -1022
 	;;
 
 	var beyond : int64 = 0
--- a/lib/math/test/fpmath-fma-impl.myr
+++ b/lib/math/test/fpmath-fma-impl.myr
@@ -33,6 +33,8 @@
 		(0x7689f580, 0x91418000, 0xaa2822ae, 0xc8508e21),
 		(0xbd813cc0, 0x421f0000, 0x9f098e17, 0xc0208977),
 		(0x3745461a, 0x4db9b736, 0xb6d7deff, 0x458f1cd8),
+		(0xa3ccfd37, 0x7f800000, 0xed328e70, 0xff800000),
+		(0xa3790205, 0x5033a3e6, 0xa001fd11, 0xb42ebbd5),
 	][:]
 
 	for (x, y, z, r) : inputs