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