Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LLVM code generation bug: decode . encode != id #67

Closed
Mathnerd314 opened this issue May 19, 2016 · 11 comments
Closed

LLVM code generation bug: decode . encode != id #67

Mathnerd314 opened this issue May 19, 2016 · 11 comments

Comments

@Mathnerd314
Copy link

I was running the serial-bench tests with CBOR commit ab0f193, and this turned up:

  test/Spec.hs:22: 
  1) cbor/cbor
       Falsifiable (after 27 tests and 4 shrinks): 
       expected: Just [SomeData 53169 70 55.3817683321392]
        but got: Just [SomeData (-12367) 70 55.3817683321392]
       [ArbSomeData {toSomeData = SomeData 53169 70 55.3817683321392}]
@Shimuuar
Copy link
Contributor

I couldn't reproduce issue. But here is observation fromIntegral (53169::Word16) == -12367::Int16.

@thoughtpolice
Copy link
Collaborator

I've written a tiny bit of code to put this bug in the regression suite, but can't reproduce this either. Can you specifically list what GHC version you're using and what platform you're running on? (e.g. GHC 7.10.3 on i386/Linux or amd64/OSX, etc).

I'll push the test addition to a branch and report back here so you can test the reduced case and see if it triggers.

@Mathnerd314
Copy link
Author

Mathnerd314 commented May 20, 2016

I was using NixOS / amd64:

  • ghc 7.10.3 from NixOS/nixpkgs@1aff127, h1i19vw3ihg4qm143ypd92y2vqchy2c0-stack-1.1.0
  • stack nightly-2016-05-08 resolver
  • the LLVM backend with --nix-packages llvm35 --ghc-options "-fllvm"

After I rebuild it without LLVM, it wasn't there; similarly for testing it in GHCi. So maybe it's a GHC codegen bug?

Currently I'm rebuilding everything with LLVM again, to see if it's still there. Edit: yep, still there

@dcoutts
Copy link
Member

dcoutts commented May 20, 2016

Thanks for investigating. Yes, not good. Should get to the bottom of it.

@thoughtpolice
Copy link
Collaborator

Confirmed with GHC 7.10.3/LLVM 3.5 and GHC 8.0.1-rc4/LLVM 3.7 - the bug from a small reproducer trips this perfectly.

thoughtpolice pushed a commit that referenced this issue May 20, 2016
This only trips under LLVM, however. Some other tests fail as well,
but this one is specific and we might as well add it at the low-low
cost of a few more seconds to run the tests.

Signed-off-by: Austin Seipp <austin@well-typed.com>
@thoughtpolice
Copy link
Collaborator

This can now be tripped by simply compiling the tests with -fllvm enabled (by adding it to a package binary-serialise-cbor in cabal.project, fixing stack.yaml or Nix expressions or whatever). Several tests fail, actually. I'll investigate a little and see if I can dig up anything.

@thoughtpolice
Copy link
Collaborator

I've minimized this quite far (thanks to -fhpc):

{-# LANGUAGE MagicHash #-}
module Main
  ( main -- :: IO ()
  ) where

import           Foreign.ForeignPtr       (withForeignPtr)
import           Foreign.Ptr
import           GHC.Exts

import           Data.ByteString          (ByteString)
import qualified Data.ByteString          as B
import qualified Data.ByteString.Internal as BS
import qualified Data.ByteString.Unsafe   as BU (unsafeTail)

withBsPtr :: (Ptr b -> a) -> ByteString -> a
withBsPtr f (BS.PS x off _) =
    BS.accursedUnutterablePerformIO $ withForeignPtr x $
        \(Ptr addr#) -> return $! (f (Ptr addr# `plusPtr` off))
{-# INLINE withBsPtr #-}

grabWord16 :: Ptr () -> Word
grabWord16 (Ptr ip#) = W# (byteSwap16# (indexWord16OffAddr# ip# 0#))
{-# INLINE grabWord16 #-}

trip :: ByteString -> Int
trip bs = fromIntegral (withBsPtr grabWord16 (BU.unsafeTail bs))
{-# INLINE trip #-}

main :: IO ()
main = print (trip $ B.pack [0x19, 0xcf, 0xb1])

Testing:

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.10.3
$ llc -version | head -2
LLVM (http://llvm.org/):
  LLVM version 3.5.2
$
$ ghc -fforce-recomp -O2 Issue67.hs && ./Issue67
[1 of 1] Compiling Main             ( Issue67.hs, Issue67.o )
Linking Issue67 ...
53169
$ ghc -fforce-recomp -O2 Issue67.hs -fllvm && ./Issue67
[1 of 1] Compiling Main             ( Issue67.hs, Issue67.o )
Linking Issue67 ...
-12367

@thoughtpolice
Copy link
Collaborator

Even smaller:

{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash    #-}

module Main
  ( main -- :: IO ()
  ) where
import           GHC.Prim
import           GHC.Word

data T = T !Addr#

t :: T
t = T "\xcf\xb1"#

grabWord16 :: T -> Word
grabWord16 (T addr#) = W# (byteSwap16# (indexWord16OffAddr# addr# 0#))

trip :: Int
trip = fromIntegral (grabWord16 t)

main :: IO ()
main = print trip

@thoughtpolice
Copy link
Collaborator

Reported as GHC bug #12095.

@thoughtpolice thoughtpolice changed the title decode . encode != id LLVM code generation bug: decode . encode != id May 21, 2016
@thoughtpolice thoughtpolice removed this from the 0.2.0.0 - Initial release milestone May 21, 2016
@thoughtpolice
Copy link
Collaborator

Not actually a GHC bug, this is our bug! Commit incoming with a fix...

@dcoutts
Copy link
Member

dcoutts commented May 23, 2016

@thoughtpolice nice work tracking it down!

thoughtpolice pushed a commit that referenced this issue Jul 18, 2016
Fixes #70 (/cc #67 for background)

Signed-off-by: Austin Seipp <austin@well-typed.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants