Well done! 

I've forgotten the context thought. Would you like to make a Trac ticket with 
the program, articulate what you think is wrong (beyond "output differs"), and 
maybe investigate a bit to narrow down the cause?

Many thanks

Simon

| -----Original Message-----
| From: David Terei [mailto:[email protected]]
| Sent: 26 October 2010 03:12
| To: Simon Peyton-Jones
| Cc: Simon Marlow; [email protected]
| Subject: Re: [nightly] 22-Sep-2010 build of HEAD on i386-unknown-linux 
(cam-02-unx)
| 
| OK old thread but some progress!
| 
| I narrowed down what I was talking about to a small test case. Follows bellow:
| 
| =====================
| 
| module Main where
| 
| import Data.Array.ST
| import Control.Monad.ST
| 
| import Data.Word
| import Data.Char
| import Numeric
| import System.IO
| 
| -- Test runner
| main = do
|   putStr "Enter a double: "
|   hFlush stdout
|   d <- double
|   print $ "Float Version (inline)  : " ++ (getLit True  $ floatD  d)
|   print $ "Float Version (noinline): " ++ (getLit False $ floatD  d)
|   print $ "Double Version          : " ++ (getLit True  $ doubleD d)
| 
| double :: IO Double
| double = do
|     x <- getLine
|     return $ read x
| 
| floatD  d = LMFloatLit d LMFloat
| doubleD d = LMFloatLit d LMDouble
| 
| -- 
-----------------------------------------------------------------------------
| -- Data types
| --
| 
| data LlvmType = LMFloat | LMDouble
| data LlvmLit  = LMFloatLit Double LlvmType
| 
| getLit :: Bool -> LlvmLit -> String
| getLit True  (LMFloatLit r LMFloat ) = fToStr   $ realToFrac r
| getLit False (LMFloatLit r LMFloat ) = fToStrNI $ realToFrac r
| getLit _     (LMFloatLit r LMDouble) = dToStr r
| 
| -- 
-----------------------------------------------------------------------------
| -- * Floating point conversion
| --
| 
| dToStr :: Double -> String
| dToStr d
|   = let bs     = doubleToBytes d
|         hex d' = case showHex d' "" of
|                      []    -> error "dToStr: too few hex digits for float"
|                      [x]   -> ['0',x]
|                      [x,y] -> [x,y]
|                      _     -> error "dToStr: too many hex digits for float"
|         str  = map toUpper $ concat . reverse . (map hex) $ bs
|     in  "0x" ++ str
| 
| fToStr :: Float -> String
| fToStr = (dToStr . realToFrac)
| 
| {-# NOINLINE fToStrNI #-}
| fToStrNI :: Float -> String
| fToStrNI = (dToStr . realToFrac)
| 
| -- 
-----------------------------------------------------------------------------
| -- Converting floating-point literals to integrals for printing
| 
| castDoubleToWord8Array :: STUArray s Int Double -> ST s (STUArray s Int Word8)
| castDoubleToWord8Array = castSTUArray
| 
| doubleToBytes :: Double -> [Int]
| doubleToBytes d
|    = runST (do
|         arr <- newArray_ ((0::Int),7)
|         writeArray arr 0 d
|         arr <- castDoubleToWord8Array arr
|         i0 <- readArray arr 0
|         i1 <- readArray arr 1
|         i2 <- readArray arr 2
|         i3 <- readArray arr 3
|         i4 <- readArray arr 4
|         i5 <- readArray arr 5
|         i6 <- readArray arr 6
|         i7 <- readArray arr 7
|         return (map fromIntegral [i0,i1,i2,i3,i4,i5,i6,i7])
|      )
| 
| =====================
| 
| If you compile this with -O and -fasm and on x86 the 'bug' occurs
| (both with 6.12.3 and HEAD):
| 
| $ ghc -fasm -O --make T.hs
| $ ./T
| Enter a double: 2.0e-2
| "Float Version (inline)  : 0x3F947AE147AE147B"
| "Float Version (noinline): 0x3F947AE140000000"
| "Double Version          : 0x3F947AE147AE147B"
| 
| If you compile the program with -fllvm or -fvia-C then the inline and
| noinline version of Float give the same (and correct) output. I
| haven't investigated the native code generator yet to find out why its
| doing this, will look into that soonish unless someone knows the
| answer already.
| 
| On 24 September 2010 19:46, Simon Peyton-Jones <[email protected]> wrote:
| > | fits into a float. I was doing this before basically be having
| > | something like ((realToFrac :: Double -> Float) . (realToFrac :: Float
| > | -> Double)). Recently GHC seems to have learned to optimise this by
| > | removing that code completely. (Before if I told GHC not to inline
| > | some stuff this stopped it doing that, but not anymore it seems).
| >
| > I'm agnostic about whether optimising realToFrac . realToFrac to the 
identity is OK
| (though I'd have thought so), but I don't think I see how it happens!   Maybe 
a RULE?
| But I don't see one.  If you can show it happening that'd be interesting.
| >
| > Simon
| >

_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to