Skip to content

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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information