Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

[X86] uint64->f32 on 32-bit Windows without SSE can have double rounding #43519

Open Quuxplusone opened 4 years ago

Quuxplusone commented 4 years ago
Bugzilla Link PR44549
Status NEW
Importance P enhancement
Reported by Craig Topper (craig.topper@gmail.com)
Reported on 2020-01-14 15:04:47 -0800
Last modified on 2020-01-14 16:57:58 -0800
Version trunk
Hardware PC Windows NT
CC craig.topper@gmail.com, efriedma@quicinc.com, llvm-bugs@lists.llvm.org, llvm-dev@redking.me.uk, spatel+llvm@rotateright.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also

On 32-bit targets without SSE we use the X87 unit to do uint64_t -> f32/f64/f80 conversions by converting a 64-bit integer into 80-bit extended precision using FILD. This is a signed conversion so then we add a fixup that is either 0 or 2^64 based on whether the original number was negative. Then we round the result if the destination type is f32 or f64.

This should work correctly assuming the the PC field in X87's FPCW is set to 80-bit. The FILD is not subject to the PC field, but the fixup FADD is.

On Windows, the PC field defaults to 64-bit. So the fixup FADD will round to the double precision. This means if we're doing a conversion from uint64_t to fp32, we'll round after the fixup FADD and round again when we do the fst to round to f32.

Conversions to f64 should fine since we'll just round after the FADD and the final rounding operation won't do anything.

Quuxplusone commented 4 years ago

If someone actually cares about bit-precise f32 values on x87, this is probably not the most important issue... we can't even emit basic arithmetic correctly.