x86 native codegen implements float2int# incorrectly
float2Int#
is supposed to truncate towards zero, but the x86 native codegen implements it as rounding (or rather, whatever rounding mode the x87 FPU is set to, which is normally rounding). The right thing appears to be to save/restore the x87 control word around the conversion operation, and temporarily set it to truncation. This is what gcc does. Code generated by gcc for truncation:
fnstcw -2(%ebp)
movw -2(%ebp), %ax
movb $12, %ah
movw %ax, -4(%ebp)
flds 8(%ebp)
fldcw -4(%ebp)
fistpl -8(%ebp)
fldcw -2(%ebp)
movl -8(%ebp), %eax
Test case:
import GHC.Exts
main = print (f2i (-2.9))
{-# NOINLINE f2i #-}
f2i :: Float -> Int
f2i (F# x) = I# (float2Int# x)
Also arith005
triggers this, when -O is on and the libraries were compiled with -fasm
.
Related: #1254 (closed)
Trac metadata
Trac field | Value |
---|---|
Version | 6.8.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler (NCG) |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | Unknown |
Architecture |