NCG miscompiles Double -> Float -> Double
I have a need to truncate a double to only float precision but then store it back in a double as I'm printing from the double to a hexadecimal representation.
To achieve this I basically do two calls to realToFrac. A test case for this is below. When I compile it with -fasm -O it appears as if '(realToFrac . realToFrac)' is changed to 'id'. (Not what actually happens as bug occurs in NCG, after Core stage, but thats how the programs behaviour is changed). This bug is specific to -fasm, compiling the program below with -fllvm or -fvia-C produces the correct results.
Test Case:
module Main where
import Numeric
import System.IO
-- Test runner
main = do
putStr "Enter a double: "
hFlush stdout
d <- double
print $ "Float Version : " ++ (fToStr $ realToFrac d)
print $ "Double Version: " ++ (dToStr d)
double :: IO Double
double = do
x <- getLine
return $ read x
dToStr :: Double -> String
dToStr d = show d
fToStr :: Float -> String
fToStr = (dToStr . realToFrac)
Output with '-fasm -O':
$ ./TestCase
Enter a double: 2.0e-2
Float Version : 2.0e-2
Double Version: 2.0e-2
Output with '-fvia-C -O':
$ ./TestCase
Enter a double: 2.0e-2
Float Version : 1.9999999552965164e-2
Double Version: 2.0e-2