Ticket #1254 (closed bug: fixed)
truncate = float2Int rule is incorrect
| Reported by: | brian@… | Owned by: | |
|---|---|---|---|
| Priority: | lowest | Milestone: | 6.8.1 |
| Component: | libraries/base | Version: | 6.7 |
| Keywords: | Cc: | ||
| Operating System: | Unknown/Multiple | Architecture: | powerpc |
| Type of failure: | Difficulty: | Easy (less than 1 hour) | |
| Test Case: | arith005 | Blocked By: | |
| Blocking: | Related Tickets: |
Description
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.
