Opened 3 years ago

Closed 3 years ago

#4441 closed bug (fixed)

NCG miscompiles Double -> Float -> Double

Reported by: dterei Owned by: simonmar
Priority: normal Milestone: 7.2.1
Component: Compiler (NCG) Version: 7.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: x86
Type of failure: Incorrect result at runtime Difficulty:
Test Case: Blocked By:
Blocking: Related Tickets:

Description (last modified by dterei)

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

Change History (7)

comment:1 Changed 3 years ago by dterei

  • Description modified (diff)

comment:2 Changed 3 years ago by dterei

  • Owner set to dterei

comment:3 Changed 3 years ago by simonmar

Are you sure this is the same bug? On x86 there are often floating-point differences between -fasm and -fvia-C, due to the difference in precision between x87 registers (80 bits) and in-memory values (32 or 64-bits). Try using -fasm with -msse2 to get more consistent results, or -fvia-C with -fexcess-precision to get inconsistent results with the C backend.

comment:4 Changed 3 years ago by simonmar

  • Owner changed from dterei to simonmar

Never mind, I see what the problem is. The NCG is compiling float2Double# and double2Float# into NOP in the x86/x87 backend.

comment:5 Changed 3 years ago by igloo

  • Milestone set to 7.0.2

comment:6 Changed 3 years ago by igloo

  • Milestone changed from 7.0.2 to 7.2.1

comment:7 Changed 3 years ago by simonmar

  • Resolution set to fixed
  • Status changed from new to closed

Fixed:

Wed Mar 30 03:18:09 PDT 2011  Simon Marlow <marlowsd@gmail.com>
  * implement double-to-float narrowing in the x86 NCG (#4441)
Note: See TracTickets for help on using tickets.