truncate = float2Int rule is incorrect
This is only on powerpc...
$ cat Test.hs
module Main where
f = read "2147483648" :: Float -- Hack to prevent inlining
main = print (truncate f :: Int)
b@brian:~$ ghc -no-recomp -O Test.hs && ./a.out
2147483647
b@brian:~$ ghc -no-recomp -O Test.hs -frules-off && ./a.out
-2147483648
In GHC.Float we have
{-# RULES "truncate/Float->Int" truncate = float2Int #-}
...
float2Int (F# x) = I# (float2Int# x)
But when there is oveflow float2Int# on PPC doesn't behave the same way as fromIntegral . (truncate::Float -> Integer), it does on x86 though.
I'm not sure if this should be fixed in the libraries or in the codegen. I'd probably argue that float2Int# should stay the same though, so programmers have access to a fast float to int conversion when they know overflow isn't an issue. Something like uncheckedFloat2Int# (like the shift ops) with a float2Int# wrapper is probably right.
As a side note, the builtin rule in PrelRules for float2Int is also incorrect as it goes via Integer. If float2Int# in the codegen is modified this will become correct but if the uncheckedFloat2Int# route is taken then that rule should probably be fixed.
I may fix this sometime, but for now I just wanted to document it.
Trac metadata
Trac field | Value |
---|---|
Version | 6.7 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | lowest |
Resolution | Unresolved |
Component | libraries/base |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | Multiple |
Architecture |