Message ID | CA+yXCZBs2KDYzJz=--5SjyEJz8s8sn_jtvjDyrU0dJL+L+=MzA@mail.gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | hardfloat: fix float32/64 fused multiply-add | expand |
On Sat, Mar 23, 2019 at 01:39:26 +0800, Kito Cheng wrote: > hardfloat fused multiply-add might fallback to softfloat mode in some > situation, but it might already changed the value of input operands, > so we must restore those value before fallback. > > This bug is catched by running gcc testsuite on RISC-V qemu. > > Signed-off-by: Kito Cheng <kito.cheng@gmail.com> Good catch! I'll send a v2 shortly with some small changes. Thanks, Emilio
diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 4610738..f53f391 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1596,6 +1596,7 @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s) } ur.h = up.h + uc.h; } else { + union_float32 ux = ua, uy = uc; if (flags & float_muladd_negate_product) { ua.h = -ua.h;
hardfloat fused multiply-add might fallback to softfloat mode in some situation, but it might already changed the value of input operands, so we must restore those value before fallback. This bug is catched by running gcc testsuite on RISC-V qemu. Signed-off-by: Kito Cheng <kito.cheng@gmail.com> --- fpu/softfloat.c | 7 +++++++ 1 file changed, 7 insertions(+) } @@ -1608,6 +1609,8 @@ float32_muladd(float32 xa, float32 xb, float32 xc, int flags, float_status *s) if (unlikely(f32_is_inf(ur))) { s->float_exception_flags |= float_flag_overflow; } else if (unlikely(fabsf(ur.h) <= FLT_MIN)) { + ua.h = ux.h; + uc.h = uy.h; goto soft; } } @@ -1662,6 +1665,8 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s) } ur.h = up.h + uc.h; } else { + union_float64 ux = ua, uy = uc; + if (flags & float_muladd_negate_product) { ua.h = -ua.h; } @@ -1674,6 +1679,8 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s) if (unlikely(f64_is_inf(ur))) { s->float_exception_flags |= float_flag_overflow; } else if (unlikely(fabs(ur.h) <= FLT_MIN)) { + ua.h = ux.h; + uc.h = uy.h; goto soft; } }