Done! http://hackage.haskell.org/trac/ghc/ticket/4441
Test case much simpler now. On 26 October 2010 18:24, Simon Peyton-Jones <[email protected]> wrote: > 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
