llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
28.41k stars 11.74k forks source link

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

Open topperc opened 4 years ago

topperc commented 4 years ago
Bugzilla Link 44549
Version trunk
OS Windows NT
CC @topperc,@efriedma-quic,@RKSimon,@rotateright

Extended Description

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.

efriedma-quic 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.