GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2024-03-23T22:14:54Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/24507Unsound optimization breaks pattern matching on sum type2024-03-23T22:14:54ZStefano DebenedettiUnsound optimization breaks pattern matching on sum type## Summary
Enabling `-O2` makes a case expression pattern match pick the 7th constructor of a sum type also when called with any constructor from the 2nd to the 6th.
The following factors seem to concur in triggering this behaviour (se...## Summary
Enabling `-O2` makes a case expression pattern match pick the 7th constructor of a sum type also when called with any constructor from the 2nd to the 6th.
The following factors seem to concur in triggering this behaviour (see the Expected behaviour section below for more details):
* `-O2`
* usage of the `streamly-core` library (I could not reproduce without it)
* a strictness annotation on the type used to hold the constructor to pass to the buggy function
* splitting the code into separate modules
On the other hand, using `Debug.Trace.trace` to examine the constructor before feeding it into the case expression fixes the issue, making it a Heisenbug.
## Steps to reproduce
```
$ git clone https://github.com/demaledetti/test-bug
$ cd test-bug
$ cabal clean && cabal build --ghc-options -v > cabal.log.ko 2>&1 && for i in {A..J}; do cabal run testbug -- $i; done
parser: A
testbug: src/TestBug/Parser.hs:(15,18)-(25,34): Non-exhaustive patterns in case
parser: B
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: C
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: D
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: E
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: F
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: G
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: H
OK
parser: I
OK
parser: J
testbug: src/TestBug/Parser.hs:(15,18)-(25,34): Non-exhaustive patterns in case
```
## Expected behaviour
With `-O1`:
```
$ cabal clean && cabal build -O1 --ghc-options -v > cabal.log.ok 2>&1 && for i in {A..J}; do cabal run -O1 testbug -- $i; done
parser: A
testbug: src/TestBug/Parser.hs:(15,18)-(25,34): Non-exhaustive patterns in case
parser: B
OK
parser: C
OK
parser: D
OK
parser: E
OK
parser: F
OK
parser: G
testbug: Prelude.undefined
CallStack (from HasCallStack):
undefined, called at src/TestBug/Parser.hs:23:10 in test-bug-0.1.0.0-inplace:TestBug.Parser
parser: H
OK
parser: I
OK
parser: J
testbug: src/TestBug/Parser.hs:(15,18)-(25,34): Non-exhaustive patterns in case
```
For other ways to get the correct behaviour without lowering the optimization level, including the ones mentioned in the Summary section above, see these comments in the source code:
```
$ grep -rnI "the bug" src/ testbug/
src/TestBug/Data.hs:12: -- simplifying it away makes the bug disappear
src/TestBug/Parser.hs:5:-- makes the bug go away (making it a Heisenbug)
src/TestBug/Parser.hs:16: -- uncommenting the next line makes the bug disappear
src/TestBug/Parser.hs:26: -- uncommenting the next line makes the bug disappear
testbug/Main.hs:13:-- makes the bug go away
```
## Environment
* GHC version used: 9.8.2
Optional:
* Operating System:
* System Architecture:
```
$ uname -a
Linux eppere 6.7.5-gentoo #1 SMP Mon Feb 19 15:51:31 CET 2024 x86_64 Intel(R) Core(TM) i7-1065G7 CPU @ 1.30GHz GenuineIntel GNU/Linux
```
Logs mentioned above:
[cabal.log.ko](/uploads/5c86dcaaac0efe1a297a3534d2e6b3a4/cabal.log.ko)
[cabal.log.ok](/uploads/aa5c0a45405cbf6e9fad05b1219dcd07/cabal.log.ok)
Log of build with `-O2` but removing the strictness annotation in `Main.hs` (commenting line 14, uncommenting line 15):
[cabal.log.lazy](/uploads/b63f0ae3c422538bb04ed7b623c49c50/cabal.log.lazy)
(easier to diff vs cabal.log.ko)9.8.3Andreas KlebingerAndreas Klebingerhttps://gitlab.haskell.org/ghc/ghc/-/issues/23899Nightly primops test failed on Darwin2023-09-07T09:41:40ZBryan Rbryan@haskell.foundationNightly primops test failed on DarwinJob [#1649852](https://gitlab.haskell.org/ghc/test-primops/-/jobs/1649852) failed for test-primops@e7d5ce0be2f2a56fc2103ae3d2267101fcfc8f7f
Via nightly pipeline https://gitlab.haskell.org/ghc/ghc/-/pipelines/83410Job [#1649852](https://gitlab.haskell.org/ghc/test-primops/-/jobs/1649852) failed for test-primops@e7d5ce0be2f2a56fc2103ae3d2267101fcfc8f7f
Via nightly pipeline https://gitlab.haskell.org/ghc/ghc/-/pipelines/834109.8.2Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/23003Programs loop forever when run with --nonmoving-gc on Windows using GHC 9.4.4+2024-02-15T19:03:59ZRyan ScottPrograms loop forever when run with --nonmoving-gc on Windows using GHC 9.4.4+Given the following program:
```hs
module Main where
main :: IO ()
main = putStrLn "Hello, World!"
```
If you compile this with GHC 9.4.4 or GHC 9.6.1-alpha3, you will be able to run it with the default RTS options:
```
$ ghc-9.4.4 M...Given the following program:
```hs
module Main where
main :: IO ()
main = putStrLn "Hello, World!"
```
If you compile this with GHC 9.4.4 or GHC 9.6.1-alpha3, you will be able to run it with the default RTS options:
```
$ ghc-9.4.4 Main.hs
[1 of 2] Compiling Main ( Main.hs, Main.o )
[2 of 2] Linking Main.exe
$ ./Main.exe
Hello, World!
```
If you try to run it with the `--nonmoving-gc` RTS option, however, then the program will loop forever:
```
$ ./Main.exe +RTS --nonmoving-gc -RTS
Hello, World!
# The program hangs at this point, and Ctrl-C is not enough to kill it.
# The program must be manually killed with the Task Manager.
```
In larger applications, this bug has likely been responsible for access violations instead of infinite loops (see [here](https://github.com/haskell/filepath/pull/181#issuecomment-1435732101) for an example).
This is a regression from GHC 9.2.6, which does not exhibit this issue:
```
$ ghc-9.2.6 Main.hs
[1 of 1] Compiling Main ( Main.hs, Main.o )
Linking Main.exe ...
$ ./Main.exe +RTS --nonmoving-gc -RTS
Hello, World!
$ ./Main.exe
Hello, World!
```9.10.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/22998Wrong result for modulo arithmetic with GHC 9.42023-09-18T21:44:50ZLars KuhtzWrong result for modulo arithmetic with GHC 9.4## Summary
With GHC-9.4.4 and optimization enabled (`-O1` or `-O2`) I have been observing erroneous results for `newtype`s over `Mod q` from the `mod` package for q ≥ 2^64.
The buggy behavior appears only with GHC-9.4 and only when op...## Summary
With GHC-9.4.4 and optimization enabled (`-O1` or `-O2`) I have been observing erroneous results for `newtype`s over `Mod q` from the `mod` package for q ≥ 2^64.
The buggy behavior appears only with GHC-9.4 and only when optimization is enabled. This indicates that it may be a bug in GHC-9.4. Moreover, the manifestation of the bug is somewhat non-deterministic. In particular it varies based on where code is placed (same or other module) and whether unrelated code is compiled along with the problematic code.
## Steps to reproduce
Building and running the following program with `cabal run -w ghc-9.4.4 Main.hs` (`-O1` enabled) prints `0` to the terminal.
```Haskell
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Main (main) where
import Data.Mod (Mod)
import GHC.TypeNats (KnownNat)
import Numeric.Natural (Natural)
import Test.QuickCheck (Arbitrary, arbitrary)
import Test.QuickCheck.Instances ()
newtype Fq = Fq (Mod 18446744073709551616 {- 2^64 -}) deriving (Num)
instance KnownNat n => Arbitrary (Mod n) where
arbitrary = fromIntegral <$> arbitrary @Natural
instance Arbitrary Fq where
arbitrary = Fq <$> arbitrary
main :: IO ()
main = let Fq x = -1 in print x
-- the result will be the same for value of -2, -3, ... or 0 - 1.
```
Note, that in this example the redundant `Arbitrary` instances are required for the bug to manifest. On larger code bases I have observed the bug also without these instances in the code base.
Build dependencies:
```cabal
cabal-version: 3.0
name: mod-bug
version: 0.1.0.0
synopsis: demonstrate bug when using mod package
executable bug
main-is: Main.hs
hs-source-dirs: .
default-language: Haskell2010
build-depends:
, base ==4.17.0.0
, mod ==0.2.0.1
, QuickCheck ==2.14.2
, quickcheck-instances ==0.3.28
```
Please also see [this Github issue](https://github.com/Bodigrim/mod/issues/25) and [this gist](https://gist.github.com/larskuhtz/c216e2fd9e6aac580ea9640d554dddf8) for further details.
## Expected behavior
Above program should print: `18446744073709551615`
## Environment
GHC-9.4.4, amd64, build with `-O1` or `-O2`. The bug has been reproduced both with Linux and MacOS.
I have not been able to reproduce the bug with other versions of GHC or with `-O0`. I haven't tried on arm architectures.9.4.5Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/22816Compose's Show/Show1 and Read/Read1 instances no longer agree in GHC 9.6.1-al...2023-01-26T23:12:05ZRyan ScottCompose's Show/Show1 and Read/Read1 instances no longer agree in GHC 9.6.1-alpha1As of `base-4.18.0.0` (as bundled with GHC 9.6.1-alpha1), the behavior of `Compose`'s `Show` instance no longer agrees with its `Show1` instance. By that, I mean that if you run the following program:
```hs
module Main where
import Dat...As of `base-4.18.0.0` (as bundled with GHC 9.6.1-alpha1), the behavior of `Compose`'s `Show` instance no longer agrees with its `Show1` instance. By that, I mean that if you run the following program:
```hs
module Main where
import Data.Functor.Classes
import Data.Functor.Compose
ex :: Compose Maybe Maybe Int
ex = Compose Nothing
main :: IO ()
main = do
putStrLn $ showsPrec 0 ex ""
putStrLn $ showsPrec1 0 ex ""
```
You would expect `Compose Nothing` to be printed twice. Indeed, this happens with GHC 9.4.4 and earlier:
```
$ runghc-9.4.4 Bug.hs
Compose Nothing
Compose Nothing
```
But not with GHC 9.6.1-alpha1:
```
$ runghc-9.6.0.20230111 Bug.hs
Compose {getCompose = Nothing}
Compose Nothing
```
The `Show` instance now prints out the `getCompose` record selector, which it did not do in previous releases.
My guess is that this is an oversight that was accidentally introduced in commit 7beb356e944bf3415394fd6aeb7841aca5759020. The previous `Show` instance for `Compose` was defined as:
```hs
instance (Show1 f, Show1 g, Show a) => Show (Compose f g a) where
showsPrec = showsPrec1
instance (Show1 f, Show1 g) => Show1 (Compose f g) where
liftShowsPrec sp sl d (Compose x) =
showsUnaryWith (liftShowsPrec sp' sl') "Compose" d x
where
sp' = liftShowsPrec sp sl
sl' = liftShowList sp sl
```
Note that this uses `showsUnaryWith`, which does _not_ print the record selector. After commit 7beb356e944bf3415394fd6aeb7841aca5759020, however, the `Show` instance for `Compose` is now derived:
```hs
deriving instance Show (f (g a)) => Show (Compose f g a)
```
Derived `Show` instances always show record selectors if they are defined, which would explain the difference. One possible to fix the issue would be to change the `Show` instance to:
```hs
instance Show (f (g a)) => Show (Compose f g a) where
showsPrec d (Compose x) =
showsUnaryWith showsPrec "Compose" d x
```
-----
A similar bug exists for `Compose`'s now-derived `Read` instance, which also disagrees with its `Read1` instance. This can be seen by running this program:
```hs
module Main where
import Data.Functor.Compose
main :: IO ()
main = print (read "Compose Nothing" :: Compose Maybe Maybe Int)
```
This succeeds on GHC 9.4.4 and earlier:
```
$ runghc-9.4.4 Bug.hs
Compose Nothing
```
But fails with GHC 9.6.1-alpha1:
```
$ runghc-9.6.0.20230111 Bug.hs
Compose {getCompose = Bug.hs: Prelude.read: no parse
```
cc @Ericson23149.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/22813Runtime behavior of `structs` library changes with GHC 9.6.1-alpha12023-02-17T01:31:59ZRyan ScottRuntime behavior of `structs` library changes with GHC 9.6.1-alpha1Running the test suite of the `structs` library on Hackage fails with GHC 9.6.1-alpha1, which does not happen with earlier versions of GHC. I've minimized the phenomenon to this standalone reproducer:
<details>
```hs
{-# LANGUAGE GHC20...Running the test suite of the `structs` library on Hackage fails with GHC 9.6.1-alpha1, which does not happen with earlier versions of GHC. I've minimized the phenomenon to this standalone reproducer:
<details>
```hs
{-# LANGUAGE GHC2021 #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE ViewPatterns #-}
module Main (main) where
import Control.Monad.ST
import Data.Coerce
import GHC.Exts
import GHC.ST
newtype LinkedList a s = LinkedList (Object s)
instance Struct (LinkedList a) where
struct = Dict
instance Eq (LinkedList a s) where
(==) = eqStruct
val :: forall a. Field (LinkedList a) a
val = field 0
{-# INLINE val #-}
next :: forall a. Slot (LinkedList a) (LinkedList a)
next = slot 1
{-# INLINE next #-}
newLinkedList ::
forall a. forall m.
PrimMonad m =>
a -> LinkedList a (PrimState m) -> m (LinkedList a (PrimState m))
newLinkedList val' next'
= st
(do this <- allocLinkedList
((setField val) this) val'
((set next) this) next'
return this)
allocLinkedList ::
forall a. forall m. PrimMonad m => m (LinkedList a (PrimState m))
allocLinkedList = alloc 2
{-# INLINE allocLinkedList #-}
-- Make an empty linked list
mkEmptyLinkedList :: LinkedList a s
mkEmptyLinkedList = Nil
-- Make a linked list node with a value
mkLinkedListNode :: PrimMonad m => a -> m (LinkedList a (PrimState m))
mkLinkedListNode a = newLinkedList a Nil
-- Convert a haskell list to a linked list
listToLinkedList :: PrimMonad m => [a] -> m (LinkedList a (PrimState m))
listToLinkedList [] = return mkEmptyLinkedList
listToLinkedList (x:xs) = do
head' <- mkLinkedListNode x
rest <- listToLinkedList xs
set next head' rest
return head'
main :: IO ()
main = print $ runST $ do
let xs :: [Int]
xs = []
lxs <- listToLinkedList xs
listEqLinkedList xs lxs
-- Return if a list equal to some linked list representation.
listEqLinkedList :: PrimMonad m => Eq a => [a] -> LinkedList a (PrimState m) -> m Bool
listEqLinkedList [] l = return $ isNil l
listEqLinkedList (x:xs) l = do
xval <- getField val l
if xval == x
then do
l' <- get next l
listEqLinkedList xs l'
else return False
-----
-- Control.Monad.Primitive
-----
class Monad m => PrimMonad m where
type PrimState m
primitive :: (State# (PrimState m) -> (# State# (PrimState m), a #)) -> m a
class PrimMonad m => PrimBase m where
internal :: m a -> State# (PrimState m) -> (# State# (PrimState m), a #)
instance PrimMonad (ST s) where
type PrimState (ST s) = s
primitive = ST
{-# INLINE primitive #-}
instance PrimBase (ST s) where
internal (ST p) = p
{-# INLINE internal #-}
primitive_ :: PrimMonad m
=> (State# (PrimState m) -> State# (PrimState m)) -> m ()
{-# INLINE primitive_ #-}
primitive_ f = primitive (\s# ->
case f s# of
s'# -> (# s'#, () #))
primToPrim :: (PrimBase m1, PrimMonad m2, PrimState m1 ~ PrimState m2)
=> m1 a -> m2 a
{-# INLINE primToPrim #-}
primToPrim m = primitive (internal m)
-----
-- Data.Struct.Internal
-----
data Dict p where
Dict :: p => Dict p
st :: PrimMonad m => ST (PrimState m) a -> m a
st = primToPrim
{-# INLINE[0] st #-}
class Struct t where
struct :: Dict (Coercible (t s) (Object s))
data Object s = Object { runObject :: SmallMutableArray# s Any }
coerceF :: Dict (Coercible a b) -> a -> b
coerceF Dict = coerce
{-# INLINE coerceF #-}
coerceB :: Dict (Coercible a b) -> b -> a
coerceB Dict = coerce
{-# INLINE coerceB #-}
destruct :: Struct t => t s -> SmallMutableArray# s Any
destruct = \x -> runObject (coerceF struct x)
{-# INLINE destruct #-}
construct :: Struct t => SmallMutableArray# s Any -> t s
construct = \x -> coerceB struct (Object x)
{-# INLINE construct #-}
eqStruct :: Struct t => t s -> t s -> Bool
eqStruct = \x y -> isTrue# (destruct x `sameSmallMutableArray#` destruct y)
{-# INLINE eqStruct #-}
alloc :: (PrimMonad m, Struct t) => Int -> m (t (PrimState m))
alloc (I# n#) = primitive $ \s -> case newSmallArray# n# undefined s of (# s', b #) -> (# s', construct b #)
writeSmallMutableArraySmallArray# :: SmallMutableArray# s Any -> Int# -> SmallMutableArray# s Any -> State# s -> State# s
writeSmallMutableArraySmallArray# m i a s = unsafeCoerce# writeSmallArray# m i a s
{-# INLINE writeSmallMutableArraySmallArray# #-}
readSmallMutableArraySmallArray# :: SmallMutableArray# s Any -> Int# -> State# s -> (# State# s, SmallMutableArray# s Any #)
readSmallMutableArraySmallArray# m i s = unsafeCoerce# readSmallArray# m i s
{-# INLINE readSmallMutableArraySmallArray# #-}
casSmallMutableArraySmallArray# :: SmallMutableArray# s Any -> Int# -> SmallMutableArray# s Any -> SmallMutableArray# s Any -> State# s -> (# State# s, Int#, SmallMutableArray# s Any #)
casSmallMutableArraySmallArray# m i o n s = unsafeCoerce# casSmallArray# m i o n s
{-# INLINE casSmallMutableArraySmallArray# #-}
data Slot x y = Slot
(forall s. SmallMutableArray# s Any -> State# s -> (# State# s, SmallMutableArray# s Any #))
(forall s. SmallMutableArray# s Any -> SmallMutableArray# s Any -> State# s -> State# s)
(forall s. SmallMutableArray# s Any -> SmallMutableArray# s Any -> SmallMutableArray# s Any -> State# s -> (# State# s, Int#, SmallMutableArray# s Any #))
slot :: Int {- ^ slot -} -> Slot s t
slot (I# i) = Slot
(\m s -> readSmallMutableArraySmallArray# m i s)
(\m a s -> writeSmallMutableArraySmallArray# m i a s)
(\m o n s -> casSmallMutableArraySmallArray# m i o n s)
get :: (PrimMonad m, Struct x, Struct y) => Slot x y -> x (PrimState m) -> m (y (PrimState m))
get (Slot go _ _) = \x -> primitive $ \s -> case go (destruct x) s of
(# s', y #) -> (# s', construct y #)
{-# INLINE get #-}
set :: (PrimMonad m, Struct x, Struct y) => Slot x y -> x (PrimState m) -> y (PrimState m) -> m ()
set (Slot _ go _) = \x y -> primitive_ (go (destruct x) (destruct y))
{-# INLINE set #-}
data Field x a = Field
(forall s. SmallMutableArray# s Any -> State# s -> (# State# s, a #)) -- get
(forall s. SmallMutableArray# s Any -> a -> State# s -> State# s) -- set
field :: Int {- ^ slot -} -> Field s a
field (I# i) = Field
(\m s -> unsafeCoerce# readSmallArray# m i s)
(\m a s -> unsafeCoerce# writeSmallArray# m i a s)
{-# INLINE field #-}
getField :: (PrimMonad m, Struct x) => Field x a -> x (PrimState m) -> m a
getField (Field go _) = \x -> primitive (go (destruct x))
{-# INLINE getField #-}
setField :: (PrimMonad m, Struct x) => Field x a -> x (PrimState m) -> a -> m ()
setField (Field _ go) = \x y -> primitive_ (go (destruct x) y)
{-# INLINE setField #-}
data Box = Box Null
data Null = Null
isNil :: Struct t => t s -> Bool
isNil t = isTrue# (unsafeCoerce# reallyUnsafePtrEquality# (destruct t) Null)
{-# INLINE isNil #-}
pattern Nil :: Struct t => () => t s
pattern Nil <- (isNil -> True) where
Nil = unsafeCoerce# Box Null
```
</details>
The intended behavior is that this program should print `True`. GHC 9.4.4 does this:
```
$ ghc-9.4.4 Bug.hs -O -fforce-recomp
[1 of 2] Compiling Main ( Bug.hs, Bug.o )
[2 of 2] Linking Bug [Objects changed]
$ ./Bug
True
```
But GHC 9.6.1-alpha1 prints `False` instead:
```
$ ghc-9.6.0.20230111 Bug.hs -O -fforce-recomp
[1 of 2] Compiling Main ( Bug.hs, Bug.o )
[2 of 2] Linking Bug [Objects changed]
$ ./Bug
False
```
A couple of observations:
* Is this code's behavior well defined? Admittedly, it is a rather advanced Edward Kmett library that makes heavy use of `unsafeCoerce#` and `reallyUnsafePointerEquality#`. (See also #12669.) Still, the behavior of this library has remained remarkably stable for several GHC releases, so I figured that a change in behavior is probably worth looking into.
* Speaking of `reallyUnsafePointerEquality#`, there have been some changes surrounding this function in #17126 and #20863. I'm unclear if these changes are responsible for the change in behavior seen above.9.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/22666containers intset-benchmark takes a long time to run on HEAD.2023-03-31T09:33:30ZAndreas Klebingercontainers intset-benchmark takes a long time to run on HEAD.Works with 9.4.2:
```
Pandi@Ryzen MINGW64 ~/repos/containers
$ cabal run -w ghc-9.4.2 --allow-newer=* intset-benchmarks -- -p All.member
Up to date
All
member: OK (2.44s)
37.2 μs ± 2.6 μs
All 1 tests passed (2.44s)
```
But with ...Works with 9.4.2:
```
Pandi@Ryzen MINGW64 ~/repos/containers
$ cabal run -w ghc-9.4.2 --allow-newer=* intset-benchmarks -- -p All.member
Up to date
All
member: OK (2.44s)
37.2 μs ± 2.6 μs
All 1 tests passed (2.44s)
```
But with HEAD this takes forever. I eventually killed the process as I got bored of waiting
```
$ time cabal --store-dir store-head run --builddir=dist-head -w /home/andi/ghc_head/_build/stage1/bin/ghc --allow-newer=* intset-benchmarks -- -p All.member
Up to date
All
member: This benchmark takes more than 100 seconds. Consider setting --timeout, if this is unexpected (or to silence this warning).
real 3m23.322s
user 0m0.000s
sys 0m0.015s
```
Seems pretty bad.9.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/22492Program produces <<loop>> with GHC 9.0/9.2, but not with GHC 8.102022-12-09T20:15:38ZRyan ScottProgram produces <<loop>> with GHC 9.0/9.2, but not with GHC 8.10While attempting to upgrade the [`saw-script`]() project, I have noticed that it will produce a runtime `<<loop>>` on GHC 9.0 and 9.2 on a program that did not used to `<<loop>>` with GHC 8.10. I believe this to be a regression, so I am ...While attempting to upgrade the [`saw-script`]() project, I have noticed that it will produce a runtime `<<loop>>` on GHC 9.0 and 9.2 on a program that did not used to `<<loop>>` with GHC 8.10. I believe this to be a regression, so I am reporting it here. Unfortunately, I have not been able to minimize the issue, but you can perform the following steps:
1. Ensure you have Clang installed. In case it is important, I am using Clang 10.0.0 on 64-bit Ubuntu 20.04:
```
$ clang --version
clang version 10.0.0-4ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
```
2. Clone https://github.com/GaloisInc/saw-script, enter the `saw-script` directory, and check out the `ghc-9.0-9.2-bug` branch:
```
$ git clone https://github.com/GaloisInc/saw-script
$ cd saw-script
$ git checkout ghc-9.0-9.2-bug
```
3. Put the following files in the `saw-script` directory:
```c
// column.c
typedef enum {
ColumnA = 0,
ColumnB,
} Column;
int is_column_a(Column c) {
return c == ColumnA;
}
```
```
// column.saw
```
```
// bug.saw
enable_experimental;
env <- heapster_init_env "column" "column.bc";
heapster_define_perm env "int32" " " "llvmptr 32" "exists x:bv 32.eq(llvmword(x))";
heapster_define_perm env "Column" ""
"llvmptr 32"
"eq(llvmword(0)) or eq(llvmword(1))";
heapster_typecheck_fun env "is_column_a"
"().arg0:Column<> -o ret:int32<>";
```
4. Compile `column.c` with Clang like so:
```
$ clang-10 -emit-llvm -c column.c -o column.bc
```
5. Run the following command to run `saw` using GHC 8.10.7, which should succeed:
```
$ cabal run exe:saw -w ghc-8.10.7 -- bug.saw
Resolving dependencies...
Up to date
[00:19:37.163] Loading file "/home/ryanglscott/Documents/Hacking/Haskell/saw-script/bug.saw"
```
6. Now run the same command with GHC 9.0.2 or 9.2.4. These will loop:
```
$ cabal run exe:saw -w ghc-9.0.2 -- bug.saw
Resolving dependencies...
Up to date
[00:21:46.189] Loading file "/home/ryanglscott/Documents/Hacking/Haskell/saw-script/bug.saw"
[00:21:46.531] <<loop>>
```
```
$ cabal run exe:saw -w ghc-9.2.4 -- bug.saw
Resolving dependencies...
Up to date
[00:22:49.344] Loading file "/home/ryanglscott/Documents/Hacking/Haskell/saw-script/bug.saw"
[00:22:49.682] <<loop>>
```
Note that you should only use GHC 9.2.4 or earlier, not 9.2.5, as GHC 9.2.5 will trigger #22491.Ryan ScottRyan Scotthttps://gitlab.haskell.org/ghc/ghc/-/issues/22421Data race in `readTVarIO#`?2023-08-22T17:49:54ZBen GamariData race in `readTVarIO#`?Currently `readTVarIO#` is defined thusly (annotations are my own):
```c
stg_readTVarIOzh ( P_ tvar /* :: TVar a */ )
{
W_ result, resultinfo;
again:
result = StgTVar_current_value(tvar);
...Currently `readTVarIO#` is defined thusly (annotations are my own):
```c
stg_readTVarIOzh ( P_ tvar /* :: TVar a */ )
{
W_ result, resultinfo;
again:
result = StgTVar_current_value(tvar);
// (1)
resultinfo = %INFO_PTR(result);
prim_read_barrier; // (2)
if (resultinfo == stg_TREC_HEADER_info) {
goto again;
}
return (result);
}
```
I'm skeptical that the barriers here are correct. In particular, it seems to me that there should be a read barrier between the load from `tvar->current_value` and the `%INFO_PTR` load (point (1)). Secondly, I don't believe that the barrier at (2) is necessary.
IMHO, this is all much easier to reason about with C11-style release acquire semantics. Under this worldview, the load from `current_value` should be an acquire-load, which will synchronize with the release-store in `unlock_tvar`. This will guarantee a happens-before relationship, which then allows us to conclude that the barrier at (2) is redundant since the construction of the closure necessarily happens-before the store in `unlock_tvar`.Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/22282GHC 9.4.2 regresses being able to do math on aarch642023-03-14T12:26:02ZJade LovelaceGHC 9.4.2 regresses being able to do math on aarch64## Summary
I found this test failure while working on nixpkgs on aarch64. This is *extremely alarming*, before I reduced it to a simpler program using only base, at which point I am out-of-this-world alarmed.
https://github.com/haskell...## Summary
I found this test failure while working on nixpkgs on aarch64. This is *extremely alarming*, before I reduced it to a simpler program using only base, at which point I am out-of-this-world alarmed.
https://github.com/haskell-foundation/foundation/issues/571
## Steps to reproduce
Stick this in `Main.hs`:
```haskell
{-# LANGUAGE NoImplicitPrelude, OverloadedStrings, RankNTypes, ScopedTypeVariables, NoRebindableSyntax #-}
module Main where
import Prelude
import System.Environment
import Data.Word
testF :: Word8 -> Word8 -> Bool
testF a b =
if b == 0 then True
else a == (a `div` b) * b + (a `mod` b)
main :: IO ()
main = do
args <- getArgs
let [a :: Word8, b] = read <$> args
putStrLn . show $ testF a b
```
Then:
```
co/ghc942bug » ghc -O1 app/Main.hs
[1 of 2] Compiling Main ( app/Main.hs, app/Main.o )
[2 of 2] Linking app/Main
co/ghc942bug » app/Main 217 161
False
co/ghc942bug » ghc -O0 app/Main.hs
[1 of 2] Compiling Main ( app/Main.hs, app/Main.o ) [Optimisation flags changed]
[2 of 2] Linking app/Main [Objects changed]
co/ghc942bug » app/Main 217 161
True
```
Note that it's fine on 9.2.4:
```
co/ghc942bug » ghcup set 9.2.4
[ Warn ] This is an old-style command for setting GHC. Use 'ghcup set ghc' instead.
[ Info ] GHC 9.2.4 successfully set as default version
co/ghc942bug » ghc -O0 app/Main.hs
[1 of 1] Compiling Main ( app/Main.hs, app/Main.o )
Linking app/Main ...
co/ghc942bug » app/Main 217 161
True
co/ghc942bug » ghc -O1 app/Main.hs
[1 of 1] Compiling Main ( app/Main.hs, app/Main.o ) [Optimisation flags changed]
Linking app/Main ...
co/ghc942bug » app/Main 217 161
True
```
On Linux, GHC 9.4.2 from nixpkgs (qemu on Apple Silicon):
```
~ » ghc -O1 Repro.hs
[1 of 2] Compiling Main ( Repro.hs, Repro.o )
[2 of 2] Linking Repro
~ » ./Repro 217 161
False
~ » ghc -O0 Repro.hs
[1 of 2] Compiling Main ( Repro.hs, Repro.o ) [Optimisation flags changed]
[2 of 2] Linking Repro [Objects changed]
~ » ./Repro 217 161
True
~ » uname -a
Linux thinnix 5.15.47 #1-NixOS SMP Tue Jun 14 16:36:28 UTC 2022 aarch64 GNU/Linux
```
## Expected behavior
It should return True in both optimization configurations.
## Environment
* GHC version used: 9.4.2 from ghcup although it also happens on ghc from nix. It's fine in ghc 9.2.4.
Optional:
* Operating System: macOS, although it also happens on aarch64-linux
* System Architecture: aarch649.4.3https://gitlab.haskell.org/ghc/ghc/-/issues/22042ghc-9.4.1 runghc illegal hardware instruction2022-10-18T08:41:53ZShayne Fletchershayne@shaynefletcher.orgghc-9.4.1 runghc illegal hardware instruction## Summary
a program calling `setSGR` from the `System.Console.ANSI` package executed via `runghc` exhibits an illegal hardware instruction error.
see this [commercial-stack issue](https://github.com/commercialhaskell/stack/issues/5823...## Summary
a program calling `setSGR` from the `System.Console.ANSI` package executed via `runghc` exhibits an illegal hardware instruction error.
see this [commercial-stack issue](https://github.com/commercialhaskell/stack/issues/5823) for further insights.
## Steps to reproduce
execute
```bash
cat > Main.hs <<EOF
import System.Console.ANSI
main = do
setSGR [SetColor Foreground Dull Red]
EOF
~/ghc-9.4.1/bin/runghc -hide-all-packages -package --ghc-arg="base-4.17.0.0" -package --ghc-arg="colour-2.3.6" -package --ghc-arg="ansi-terminal-0.11.3" --ghc-arg=-package-db --ghc-arg=$HOME/.cabal/store/ghc-9.4.1/package.db Main.hs
```
and observe abnormal termination and the bash exit code `132`. (the equivalent 9.2.4 command
```
~/ghc-9.2.4/bin/runghc -hide-all-packages -package --ghc-arg="base-4.16.3.0" -package --ghc-arg="colour-2.3.6" -package --ghc-arg="ansi-terminal-0.11.3" --ghc-arg=-package-db --ghc-arg=$HOME/.cabal/store/ghc-9.2.4/package.db Main.hs
```
terminates normally. also, a "raw" ghc command
```
~/ghc-9.4.1/bin/ghc -o test -hide-all-packages -package "base-4.17.0.0" -package "colour-2.3.6" -package "ansi-terminal-0.11.3" -package-db $HOME/.cabal/store/ghc-9.4.1/package.db Main.hs&&./test
```
terminates normally too.)
## Expected behavior
terminate normally with no output and bash exit code `0`
## Environment
* GHC version used: ghc-9.4.1
Optional:
* Operating System: macOS monterey
* System Architecture: x86_649.4.2Andreas KlebingerAndreas Klebingerhttps://gitlab.haskell.org/ghc/ghc/-/issues/21708Compiled program with GHC9.2.2 often causes "internal error: evacuate: strang...2022-11-07T15:55:40ZJH LeCompiled program with GHC9.2.2 often causes "internal error: evacuate: strange closure type xxx"## Summary
I cannot come up with a good title, so please bear with me with the title.
I've been using XMonad with GHC 9.0.2 fine,
but when I updated it to GHC9.2.2, it often crashes.
It sometimes leave the following message, while somet...## Summary
I cannot come up with a good title, so please bear with me with the title.
I've been using XMonad with GHC 9.0.2 fine,
but when I updated it to GHC9.2.2, it often crashes.
It sometimes leave the following message, while sometimes silently crashes.
```
xmonad-x86_64-linux: internal error: evacuate: strange closure type 0
(GHC version 9.2.2 for x86_64_unknown_linux)
Please report this as a GHC bug: https://www.haskell.org/ghc/reportabug
Aborted (core dumped)
```
(The closure type depends time to time)
Happens with the most bare-bone XMonad instance. I am lost on how to skin it down further.
Reporting this to GHC, since this specifically happens with GHC9.2.2. All previous versions work fine.
Any directions to diagnose which part is causing the issue?
## Steps to reproduce
1. Install XMonad as dynamically linked
2. Run with the default configuration
3. (At least on my end) performing some action leads to a crash from time to time
## Expected behavior
`internal error: evacuate: strange closure type 0` should not happen.
## Environment
* GHC version used: 9.2.2
Optional:
* Operating System: Ubuntu 20.04.4 LTS, 64-bit, Linux
* System Architecture: x86-649.2.4Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/21624"IntMulMayOfloOp" primop compiles to wrong Aarch64 assembly2022-08-05T14:46:34ZNatsu Kagami"IntMulMayOfloOp" primop compiles to wrong Aarch64 assembly## Summary
The primop `IntMulMayOfloOp` is being translated to a `MUL` instruction followed by a `CSET` (conditional set, with overflow flag) instruction on Aarch64 (see https://gitlab.haskell.org/ghc/ghc/-/blob/master/compiler/GHC/CmmT...## Summary
The primop `IntMulMayOfloOp` is being translated to a `MUL` instruction followed by a `CSET` (conditional set, with overflow flag) instruction on Aarch64 (see https://gitlab.haskell.org/ghc/ghc/-/blob/master/compiler/GHC/CmmToAsm/AArch64/CodeGen.hs#L894).
However, this is not correct: the overflow flag is never set on a `MUL` instruction. According to [A64 documentation](https://developer.arm.com/documentation/100076/0100/A64-Instruction-Set-Reference/Condition-Codes/Condition-flags?lang=en),
> Overflow occurs if the result of a signed add, subtract, or compare is greater than or equal to 2^31, or less than -2^31.
This means that the current primop will most likely return 0 all the time, which is wrong and potentially dangerous.
## Steps to reproduce
The following code always prints 0 in ghc 9.2.2 on Apple M1, but not in ghc 8.10.7 (which uses LLVM backend):
```hs
{-# LANGUAGE MagicHash #-}
module Main where
import GHC.Exts
import Data.Bits
unpack (I# a#) = a#
k :: Int
k = 134534534134534000 -- obviously does not fit in an int32, and so will overflow when squared.
bakaVariable = I# (mulIntMayOflo# (unpack k) (unpack k))
main = do
print bakaVariable
```
## Expected behavior
Should not print 0 at all.
## Environment
* GHC version used: 9.2.2
Optional:
* Operating System: Mac OS Monterey 12.3.1
* System Architecture: Aarch64 (Apple M1 Macbook Air)9.2.4Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/21465128-bit Callee-saved registers (Windows x64) are not saved and restored corre...2022-05-30T17:12:27ZThomas Dinsdale-Young128-bit Callee-saved registers (Windows x64) are not saved and restored correctly## Summary
The Windows x64 calling convention requires that the 128-bit registers XMM6-XMM15 be [saved (and restored) by the callee](https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170#callercallee-saved-regi...## Summary
The Windows x64 calling convention requires that the 128-bit registers XMM6-XMM15 be [saved (and restored) by the callee](https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170#callercallee-saved-registers).
`StgRunIsImplementedInAssembler`, which handles this in the runtime, does not correctly save and restore these registers, as it uses `movq` to do so, treating them as 64-bits only.
Consequently, when the registers are restored, the high-order 64-bits are zeroed.
Instead, `movaps` should probably be used, and 16 bytes reserved for each XMM register.
The consequence of this is that FFI calls to Haskell code on Windows may violate the calling convention and lead to undefined behaviour.
## Steps to reproduce
The attached files can be compiled on Windows with `ghc Main.hs reg.c`.
[Main.hs](/uploads/625555a8de865f7114397d3d81823ef6/Main.hs)
[reg.c](/uploads/1646814458605a7f87cde873b7dbd13a/reg.c)
The Haskell main function invokes a C function `test_c`, which uses inline assembly to set a value to the XMM6 register, invoke a Haskell function `helper`, and then read out the resulting value of the XMM6 register, comparing each byte to the expected (original) value.
The output of executing `Main.exe` is:
```
This is the helper function
0: 01 01
1: 02 02
2: 03 03
3: 04 04
4: 05 05
5: 06 06
6: 07 07
7: 08 08
8: 09 00
9: 0a 00
10: 0b 00
11: 0c 00
12: 0d 00
13: 0e 00
14: 0f 00
15: 10 00
Done.
```
This indicates that the lower-order 8 bytes of the register are correctly restored after the call to `helper`, but the high-order 8 bytes are not.
This is consistent with the use of `movq` instead of `movaps` (or `movups`).
## Expected behavior
The expected output is:
```
This is the helper function
0: 01 01
1: 02 02
2: 03 03
3: 04 04
4: 05 05
5: 06 06
6: 07 07
7: 08 08
8: 09 09
9: 0a 0a
10: 0b 0b
11: 0c 0c
12: 0d 0d
13: 0e 0e
14: 0f 0f
15: 10 10
Done.
```
## Environment
* GHC version used: 9.0.2, 8.10.2
Optional:
* Operating System: Windows 8.1
* System Architecture: x86-64Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/21251Compact regions with sharing can lose pointer tags.2022-03-20T03:26:06ZAndreas KlebingerCompact regions with sharing can lose pointer tags.This caused https://gitlab.haskell.org/ghc/ghc/-/issues/21189
This issue is as follows. We create a compact region with some values.
We add a constructor with strict fields, where the fields reference values *already* in the compact re...This caused https://gitlab.haskell.org/ghc/ghc/-/issues/21189
This issue is as follows. We create a compact region with some values.
We add a constructor with strict fields, where the fields reference values *already* in the compact region.
This (eventually) results in a call to `stg_compactAddWorkerzh` in order to compact the closures the constructor fields point to, with this particular snippet being executed.
```
// Everything else we should copy and evaluate the components:
case
CONSTR,
CONSTR_1_0,
CONSTR_2_0,
CONSTR_1_1: {
(should) = ccall shouldCompact(compact "ptr", p "ptr");
if (should == SHOULDCOMPACT_IN_CNF) { P_[pp] = p; return(); }
```
pp is the address to store the result in. `p` is the *untagged* pointer. The fix is simple. Use `tag | p` instead of `p` (as this code already does in other places!).
I will put up a patch shortly.
This caused https://gitlab.haskell.org/ghc/ghc/-/issues/211899.4.1https://gitlab.haskell.org/ghc/ghc/-/issues/21229Inlining DFuns leads to an unsound interaction with Specialise2023-09-13T12:07:03ZSebastian GrafInlining DFuns leads to an unsound interaction with Specialise!7599 unveiled a bug in the Specialiser.
* See also #21328
* Test is in `simplCore/should_run/T21229`
Back to the Specialiser. Consider
```hs
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowA...!7599 unveiled a bug in the Specialiser.
* See also #21328
* Test is in `simplCore/should_run/T21229`
Back to the Specialiser. Consider
```hs
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
data B = T | F deriving Show
class Sing (b :: B) where sing :: B
instance Sing 'T where sing = T
instance Sing 'F where sing = F
f :: forall a. Sing a => Int -> (Int -> B -> B) -> B
f 0 g = g 0 (sing @a)
f n g = f @a (n-1) g
h :: forall a. Sing a => Int -> (Int -> B -> B) -> B
h = case sing @a of
T -> f @'T
F -> f @a
{-# NOINLINE h #-}
main = print $ h @'T 0 (\ _ a -> a)
```
With -O0, this prints `T`, as expected, because `h` will ultimately call its supplied argument once with `T`.
But with -O, I get `F`. Why is that? The reason is we ultimately get the following specialisation for the second call to `f`:
```
RULES: "SPEC f @a"
forall (@(a_aXu :: B)) ($dSing_s1OW :: Sing a_aXu).
f @a_aXu $dSing_s1OW
= $sf_s1OX @a_aXu]
```
and this specialisation (for when `$dSing_s1OW` is `F`) somehow also applies at `f @'T`.
FTR, here is the output of the `pprTrace "spec_call"` in Specialise:
```
spec_call
call info: CI{SpecType a_aXu
SpecDict F `cast` (Sym (N:Sing[0] <a_aXu>_N) :: B ~R# Sing a_aXu)}
useful: True
rule_bndrs: [a_aXu, $dSing_s1OW]
lhs_args: [TYPE: a_aXu, $dSing_s1OW]
spec_bndrs: [a_aXu]
spec_args: [TYPE: a_aXu,
F `cast` (Sym (N:Sing[0] <a_aXu>_N) :: B ~R# Sing a_aXu)]
dx_binds: []
rhs_env2: <InScope = {main g_aC8 a_aXu $cshowsPrec_aY5 $cshow_aYd
$cshowList_aYl $krep_aZ1 $krep_aZ2 $krep_aZ3 $krep_aZ4 $krep_aZ5
$krep_aZ6 ds_dZX main $fShowB $fSingF F $fSingT $tc'C:Sing
$trModule $tc'F $tc'T $tcB $tcSing f h main_s19F main_s19G
main_s1OF $trModule_s1OG $trModule_s1OH $trModule_s1OI
$trModule_s1OJ $krep_s1OK $tcB_s1OL $tcB_s1OM $tc'T_s1ON $tc'T_s1OO
$tc'F_s1OP $tc'F_s1OQ $tcSing_s1OR $tcSing_s1OS $krep_s1OT
$tc'C:Sing_s1OU $tc'C:Sing_s1OV}
IdSubst = [aKV :-> F
`cast` (Sym (N:Sing[0] <a_aXu>_N) :: B ~R# Sing a_aXu)]
TvSubst = [aKU :-> a_aXu]
CvSubst = []>
[]
```
How did it come to this?! For that we have to look at the Core of `h` that Specialise sees:
```
h = \ (@(a_aWY :: B))
($dSing_aWZ :: Sing a_aWY)
(eta_B0 :: Int)
(eta_B1 :: Int -> B -> B) ->
case $dSing_aWZ
`cast` (Main.N:Sing[0] <a_aWY>_N :: Sing a_aWY ~R# B)
of {
T ->
f @'T
(Main.T `cast` (Sym (Main.N:Sing[0] <'T>_N) :: B ~R# Sing 'T))
eta_B0
eta_B1;
F ->
f @a_aWY
(Main.F
`cast` (Sym (Main.N:Sing[0] <a_aWY>_N) :: B ~R# Sing a_aWY))
eta_B0
eta_B1
}
```
Note the second call to `f`. The type argument `a_aWY` is passed, as well as `Main.F` as the dictionary. That's strange! We should know *statically* that `a_aWY` must be `F`. (In fact, ``Main.F `cast` (Sym (Main.N:Sing[0] <a_aWY>_N) :: B ~R# Sing a_aWY)`` is unsound if `a_aWY` is instantiated to `T`, which would perhaps happen if we floated that expression out of the `F` case. I guess it doesn't matter much, at least not to this ticket.)
How did we get this code? After desugaring, we still have
```
h = \ (@(a_aXu :: B)) ($dSing_aXv :: Sing a_aXu) ->
case sing @a_aXu $dSing_aXv of {
T -> f @'T Main.$fSingT;
F -> f @a_aXu $dSing_aXv
}
```
But then gentle simplification inlines `sing` and sees that `$dSing_aXv` is `F` in the `F` case, performs a binder swap and successively inlines `F` (at least that's what I believe the Simplifier does).
Then the Specialiser can't connect `F` to the arguments `$dSing_aXv` or the type arg `a` and somehow bogs up. I suspect this happens in `specHeader`, but actually I'm not completely sure.
I couldn't reproduce with GHC 9.2 and any prior release. I see that we get the same Core pre-Specialise, but it is handled soundly there and we only get a specialisation for `T`. So perhaps we want to fix this before 9.4.9.4.1https://gitlab.haskell.org/ghc/ghc/-/issues/21141Nondeterministic segfault on simple hspec program with GHC 9.0 only2022-07-12T13:55:43ZRyan ScottNondeterministic segfault on simple hspec program with GHC 9.0 only_(Originally reported at https://github.com/ekmett/reflection/issues/51.)_
The [`reflection-2.1.6`](https://hackage.haskell.org/package/reflection-2.1.6) test suite nondeterministically segfaults on Linux and macOS when compiled with GH..._(Originally reported at https://github.com/ekmett/reflection/issues/51.)_
The [`reflection-2.1.6`](https://hackage.haskell.org/package/reflection-2.1.6) test suite nondeterministically segfaults on Linux and macOS when compiled with GHC 9.0.1 or 9.0.2. The furthest I've managed to minimize the issue is:
```hs
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main (main) where
import Control.Exception (ArithException(..), evaluate)
import Numeric.Natural (Natural)
import "hspec" Test.Hspec
import "hspec" Test.Hspec.QuickCheck
import "QuickCheck" Test.QuickCheck (Negative(..), NonNegative(..))
main :: IO ()
main = hspec spec
spec :: Spec
spec =
describe "A" $ do
describe "B" $ do
prop "identity" $
\(NonNegative (i :: Integer)) -> i `shouldBe` i
prop "should throw an Underflow exception on negative inputs" $
\(Negative (i :: Integer)) ->
evaluate (fromInteger i :: Natural) `shouldThrow` (== Underflow)
```
With GHC 8.10.7 or 9.2.1, this works as expected:
```
$ ghc-8.10.7 Bug.hs && ./Bug
Loaded package environment from /home/ryanglscott/Documents/Hacking/Haskell/ci-maintenance/checkout/ekmett/reflection/.ghc.environment.x86_64-linux-8.10.7
[1 of 1] Compiling Main ( Bug.hs, Bug.o )
Linking Bug ...
A
B
identity [✔]
+++ OK, passed 100 tests.
should throw an Underflow exception on negative inputs [✔]
+++ OK, passed 100 tests.
Finished in 0.0009 seconds
2 examples, 0 failures
$ ghc-9.2.1 Bug.hs && ./Bug
Loaded package environment from /home/ryanglscott/Documents/Hacking/Haskell/ci-maintenance/checkout/ekmett/reflection/.ghc.environment.x86_64-linux-9.2.1
[1 of 1] Compiling Main ( Bug.hs, Bug.o )
Linking Bug ...
A
B
identity [✔]
+++ OK, passed 100 tests.
should throw an Underflow exception on negative inputs [✔]
+++ OK, passed 100 tests.
Finished in 0.0013 seconds
2 examples, 0 failures
```
With GHC 9.0.2, however, this can segfault:
```
$ ghc-9.0.2 Bug.hs && ./Bug
Loaded package environment from /home/ryanglscott/Documents/Hacking/Haskell/ci-maintenance/checkout/ekmett/reflection/.ghc.environment.x86_64-linux-9.0.2
[1 of 1] Compiling Main ( Bug.hs, Bug.o )
Linking Bug ...
A
B
identity [✔]
+++ OK, passed 100 tests.
should throw an Underflow exception on negative inputs [ ]Segmentation fault (core dumped)
```
This is somewhat nondeterministic. In situations where it doesn't segfault, an incorrect runtime result will be observed:
```
$ ./Bug
A
B
identity [✔]
+++ OK, passed 100 tests.
should throw an Underflow exception on negative inputs [✘]
Failures:
Bug.hs:22:47:
1) A.B should throw an Underflow exception on negative inputs
Falsifiable (after 54 tests and 2 shrinks):
Negative {getNegative = -1}
did not get expected exception: ArithException
To rerun use: --match "/A/B/should throw an Underflow exception on negative inputs/"
Randomized with seed 1065015581
Finished in 0.0028 seconds
2 examples, 1 failure
```
This example proves remarkably resistant to minimization, as attempting to delete code in various places seemingly makes the bug disappear.9.0.3Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/20626Sub-word right-arithmetic-shifts appear to be wrong on x862023-08-02T10:17:55ZBen GamariSub-word right-arithmetic-shifts appear to be wrong on x86While validating bgamari/test-primops> in preparation for looking at #20594, I noticed that even the x86 NCG doesn't match the reference implementation. Specifically, consider this C-- program:
```c
test() {
bits64 ret;
ret = %zx...While validating bgamari/test-primops> in preparation for looking at #20594, I noticed that even the x86 NCG doesn't match the reference implementation. Specifically, consider this C-- program:
```c
test() {
bits64 ret;
ret = %zx64(%shra(242::bits8, 1));
return (ret);
}
```
I would expect this to return `(242>>1) | (1<<7) == 249`. However, when compiled with GHC 8.10.7 it returns 121, as demonstrated by this program:
```hs
{-# LANGUAGE GHCForeignImportPrim #-}
{-# LANGUAGE UnliftedFFITypes #-}
{-# LANGUAGE MagicHash #-}
module Main where
import GHC.Exts
import GHC.Ptr
import Foreign.Marshal.Alloc
foreign import prim "test" test :: Addr# -> Word#
main :: IO ()
main = do
Ptr p <- callocBytes (1*1000*1000)
print $ W# (test p)
```9.0.2Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/20594tf-random's documentation fails to build with GHC 9.2.1's haddock on aarch64-...2022-08-04T15:22:18Zsternitf-random's documentation fails to build with GHC 9.2.1's haddock on aarch64-linux## Summary
haddock shipped with GHC 9.2.1 fails to build `tf-random`'s documentation due to `haddock: internal error: dist/doc/html/tf-random/haddock-prologue1387-0.txt: hGetContents: invalid argument (invalid byte sequence)`.
This see...## Summary
haddock shipped with GHC 9.2.1 fails to build `tf-random`'s documentation due to `haddock: internal error: dist/doc/html/tf-random/haddock-prologue1387-0.txt: hGetContents: invalid argument (invalid byte sequence)`.
This seems to be due to some decoding problem that is architecture-specific as I've only have been able to reproduce it on `aarch64-linux`. Additionally, the issue doesn't seem to be limited to `haddock`, since also `Cabal` reports while building: `Warning: tf-random.cabal:0:0: UTF8 encoding problem at byte offset 1083`.
With this hint taken into account, it seems the Problem is decoding the “ł” in “Michał Pałka”.
<details>
<summary>Full build log</summary>
```
setupCompilerEnvironmentPhase
Build with /nix/store/z4wznwpkzr5swfzkmyi14nnj5rqhxzwn-ghc-9.2.1.
unpacking sources
unpacking source archive /nix/store/1nr84gxykdayb34wqhyhzapplwj6hj2x-tf-random-0.5.tar.gz
source root is tf-random-0.5
setting SOURCE_DATE_EPOCH to timestamp 1397051832 of file tf-random-0.5/tf-random.cabal
patching sources
compileBuildDriverPhase
setupCompileFlags: -package-db=/build/setup-package.conf.d -j4 +RTS -A64M -RTS -threaded -rtsopts
[1 of 1] Compiling Main ( Setup.hs, /build/Main.o )
Linking Setup ...
updateAutotoolsGnuConfigScriptsPhase
configuring
configureFlags: --verbose --prefix=/nix/store/m4c39knb9yw2c49xph4fdmm1xcggpp96-tf-random-0.5 --libdir=$prefix/lib/$compiler --libsubdir=$abi/$libname --docdir=/nix/store/pdia0inbjhx12hhyfpvavkmdnizxxbny-tf-random-0.5-doc/share/doc/tf-random-0.5 --with-gcc=gcc --package-db=/build/package.conf.d --ghc-options=-j4 +RTS -A64M -RTS --disable-split-objs --disable-library-profiling --disable-profiling --enable-shared --disable-coverage --enable-static --disable-executable-dynamic --enable-tests --disable-benchmarks --enable-library-vanilla --disable-library-for-ghci --ghc-option=-split-sections --extra-lib-dirs=/nix/store/iz9f5fjbk906c9j8zvr83skisy8mlbx7-ncurses-6.2/lib --extra-lib-dirs=/nix/store/wz31pppvk0ij3ykyafkw4xhp631b2i9m-libffi-3.4.2/lib --extra-lib-dirs=/nix/store/xwflzk66nkh7s45cqbjfmrc62qqncz3c-gmp-6.2.1/lib
Using Parsec parser
Warning: tf-random.cabal:0:0: UTF8 encoding problem at byte offset 1083
Configuring tf-random-0.5...
Dependency base >=4.2 && <5: using base-4.16.0.0
Dependency primitive >=0.3: using primitive-0.7.2.0
Dependency random: using random-1.2.1
Dependency time: using time-1.11.1.1
Source component graph: component lib
Configured component graph:
component tf-random-0.5-KP9k5IPcUYpGRNnHT8fvB9
include base-4.16.0.0
include primitive-0.7.2.0-26FrVImOeSRFMFxEAgiBFt
include random-1.2.1-4qyYj6P88hEL41FyrmzJfp
include time-1.11.1.1
Linked component graph:
unit tf-random-0.5-KP9k5IPcUYpGRNnHT8fvB9
include base-4.16.0.0
include primitive-0.7.2.0-26FrVImOeSRFMFxEAgiBFt
include random-1.2.1-4qyYj6P88hEL41FyrmzJfp
include time-1.11.1.1
System.Random.TF=tf-random-0.5-KP9k5IPcUYpGRNnHT8fvB9:System.Random.TF,System.Random.TF.Gen=tf-random-0.5-KP9k5IPcUYpGRNnHT8fvB9:System.Random.TF.Gen,System.Random.TF.Init=tf-random-0.5-KP9k5IPcUYpGRNnHT8fvB9:System.Random.TF.Init,System.Random.TF.Instances=tf-random-0.5-KP9k5IPcUYpGRNnHT8fvB9:System.Random.TF.Instances
Ready component graph:
definite tf-random-0.5-KP9k5IPcUYpGRNnHT8fvB9
depends base-4.16.0.0
depends primitive-0.7.2.0-26FrVImOeSRFMFxEAgiBFt
depends random-1.2.1-4qyYj6P88hEL41FyrmzJfp
depends time-1.11.1.1
Using Cabal-3.6.0.0 compiled by ghc-9.2
Using compiler: ghc-9.2.1
Using install prefix:
/nix/store/m4c39knb9yw2c49xph4fdmm1xcggpp96-tf-random-0.5
Executables installed in:
/nix/store/m4c39knb9yw2c49xph4fdmm1xcggpp96-tf-random-0.5/bin
Libraries installed in:
/nix/store/m4c39knb9yw2c49xph4fdmm1xcggpp96-tf-random-0.5/lib/ghc-9.2.1/aarch64-linux-ghc-9.2.1/tf-random-0.5-KP9k5IPcUYpGRNnHT8fvB9
Dynamic Libraries installed in:
/nix/store/m4c39knb9yw2c49xph4fdmm1xcggpp96-tf-random-0.5/lib/ghc-9.2.1/aarch64-linux-ghc-9.2.1
Private executables installed in:
/nix/store/m4c39knb9yw2c49xph4fdmm1xcggpp96-tf-random-0.5/libexec/aarch64-linux-ghc-9.2.1/tf-random-0.5
Data files installed in:
/nix/store/m4c39knb9yw2c49xph4fdmm1xcggpp96-tf-random-0.5/share/aarch64-linux-ghc-9.2.1/tf-random-0.5
Documentation installed in:
/nix/store/pdia0inbjhx12hhyfpvavkmdnizxxbny-tf-random-0.5-doc/share/doc/tf-random-0.5
Configuration files installed in:
/nix/store/m4c39knb9yw2c49xph4fdmm1xcggpp96-tf-random-0.5/etc
No alex found
Using ar found on system at:
/nix/store/10avvfvwvzj4y0z6zxij2qnz5pgqprg5-binutils-2.35.1/bin/ar
No c2hs found
No cpphs found
No doctest found
Using gcc version 9.3.0 given by user at:
/nix/store/1q1mif7h3lgxdaxg6j39hli5azikrfla-gcc-wrapper-9.3.0/bin/gcc
Using ghc version 9.2.1 found on system at:
/nix/store/z4wznwpkzr5swfzkmyi14nnj5rqhxzwn-ghc-9.2.1/bin/ghc
Using ghc-pkg version 9.2.1 found on system at:
/nix/store/z4wznwpkzr5swfzkmyi14nnj5rqhxzwn-ghc-9.2.1/bin/ghc-pkg
No ghcjs found
No ghcjs-pkg found
No greencard found
Using haddock version 2.26.0 found on system at:
/nix/store/z4wznwpkzr5swfzkmyi14nnj5rqhxzwn-ghc-9.2.1/bin/haddock
No happy found
Using haskell-suite found on system at: haskell-suite-dummy-location
Using haskell-suite-pkg found on system at: haskell-suite-pkg-dummy-location
No hmake found
Using hpc version 0.68 found on system at:
/nix/store/z4wznwpkzr5swfzkmyi14nnj5rqhxzwn-ghc-9.2.1/bin/hpc
Using hsc2hs version 0.68.8 found on system at:
/nix/store/z4wznwpkzr5swfzkmyi14nnj5rqhxzwn-ghc-9.2.1/bin/hsc2hs
Using hscolour version 1.24 found on system at:
/nix/store/cknsx4nddzjdm0g7vg9d9vpc9lvslscq-hscolour-1.24.4/bin/HsColour
No jhc found
Using ld found on system at:
/nix/store/579l1jpqmwjfghmlh9mnj6ykx06q2g38-binutils-wrapper-2.35.1/bin/ld.gold
No pkg-config found
Using runghc version 9.2.1 found on system at:
/nix/store/z4wznwpkzr5swfzkmyi14nnj5rqhxzwn-ghc-9.2.1/bin/runghc
Using strip version 2.35 found on system at:
/nix/store/10avvfvwvzj4y0z6zxij2qnz5pgqprg5-binutils-2.35.1/bin/strip
Using tar found on system at:
/nix/store/zfcd6sdfsfddhf5ybkarj4q241bsymn1-gnutar-1.34/bin/tar
No uhc found
building
Preprocessing library for tf-random-0.5..
Building library for tf-random-0.5..
[1 of 4] Compiling System.Random.TF.Gen ( src/System/Random/TF/Gen.hs, dist/build/System/Random/TF/Gen.o, dist/build/System/Random/TF/Gen.dyn_o )
[2 of 4] Compiling System.Random.TF.Init ( src/System/Random/TF/Init.hs, dist/build/System/Random/TF/Init.o, dist/build/System/Random/TF/Init.dyn_o )
src/System/Random/TF/Init.hs:94:5: warning: [-Wdeprecations]
In the use of `bitSize'
(imported from Data.Bits, but defined in GHC.Bits):
Deprecated: "Use 'bitSizeMaybe' or 'finiteBitSize' instead"
|
94 | | bitSize n > 64 = error "mkTFGen: case where size of Int > 64 not implemented"
| ^^^^^^^
[3 of 4] Compiling System.Random.TF ( src/System/Random/TF.hs, dist/build/System/Random/TF.o, dist/build/System/Random/TF.dyn_o )
[4 of 4] Compiling System.Random.TF.Instances ( src/System/Random/TF/Instances.hs, dist/build/System/Random/TF/Instances.o, dist/build/System/Random/TF/Instances.dyn_o )
running tests
Package has no test suites.
haddockPhase
Preprocessing library for tf-random-0.5..
Running Haddock on library for tf-random-0.5..
Warning: --source-* options are ignored when --hyperlinked-source is enabled.
100% ( 4 / 4) in 'System.Random.TF.Gen'
83% ( 5 / 6) in 'System.Random.TF.Init'
Missing documentation for:
Module header
src/System/Random/TF/Init.hs:94:5: warning: [-Wdeprecations]
In the use of `bitSize'
(imported from Data.Bits, but defined in GHC.Bits):
Deprecated: "Use 'bitSizeMaybe' or 'finiteBitSize' instead"
|
94 | | bitSize n > 64 = error "mkTFGen: case where size of Int > 64 not implemented"
| ^^^^^^^
100% ( 7 / 7) in 'System.Random.TF'
33% ( 1 / 3) in 'System.Random.TF.Instances'
Missing documentation for:
Random (src/System/Random/TF/Instances.hs:37)
randomEnum (src/System/Random/TF/Instances.hs:205)
haddock: internal error: dist/doc/html/tf-random/haddock-prologue1387-0.txt: hGetContents: invalid argument (invalid byte sequence)
builder for '/nix/store/jcfgav90wdc628xmnwy468dn5p57nj57-tf-random-0.5.drv' failed with exit code 1
```
</details>
## Steps to reproduce
Since this did not happen with GHC 9.2.1's release candidate, I've not investigated if this may have been caused by nixpkgs' build environment. To reproduce:
* Checkout nixpkgs at `a50888dc73b88ab344853c806ab63a3674728fc6`
* Run `nix-build -A haskell.packages.ghc921.tf-random` on `aarch64-linux`
## Expected behavior
Build `tf-random` successfully including its documentation and display no warnings about incorrect enconding.
## Environment
* GHC version used: 9.2.1
Optional:
* Operating System: NixOS
* System Architecture: aarch64-linux9.2.3Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/19976Mysterious issue with bytestring "LazyWord8.fromString literal" test2021-12-26T13:23:06ZBodigrimMysterious issue with bytestring "LazyWord8.fromString literal" test# Reproduction
```
git clone https://github.com/haskell/bytestring
cd bytestring
# git checkout 06cbef10f4869c6afdac210a22d9813b4f7f2fe6
```
Run tests with GHC 8.10 and 9.0, both should succeed:
```
$ cabal run -w ghc-8.10.4 prop-compi...# Reproduction
```
git clone https://github.com/haskell/bytestring
cd bytestring
# git checkout 06cbef10f4869c6afdac210a22d9813b4f7f2fe6
```
Run tests with GHC 8.10 and 9.0, both should succeed:
```
$ cabal run -w ghc-8.10.4 prop-compiled -- --hide-successes -p "LazyWord8.fromString literal"
All 1 tests passed (0.00s)
$ cabal run -w ghc-9.0.1 prop-compiled -- --hide-successes -p "LazyWord8.fromString literal"
All 1 tests passed (0.00s)
```
Now apply an innocent patch:
```
$ git show d701a2a9a51da47da8240a7d3adf2794ba891e90
--- a/Data/ByteString/Lazy/Internal.hs
+++ b/Data/ByteString/Lazy/Internal.hs
+packBytes [] = Empty
packBytes cs0 =
packChunks 32 cs0
...
packChars :: [Char] -> ByteString
+packChars [] = Empty
packChars cs0 = packChunks 32 cs0
$ git cherry-pick d701a2a9a51da47da8240a7d3adf2794ba891e90
Auto-merging Data/ByteString/Lazy/Internal.hs
```
and rerun tests.
# Expected results
Tests suceed both in GHC 8.10.4 and 9.0.1.
# Actual results
Tests succeed in GHC 8.10.4, but fail in 9.0.1:
```
$ cabal run -w ghc-8.10.4 prop-compiled -- --hide-successes -p "LazyWord8.fromString literal"
All 1 tests passed (0.00s)
$ cabal run -w ghc-9.0.1 prop-compiled -- --hide-successes -p "LazyWord8.fromString literal"
All
LazyWord8
fromString literal: FAIL
*** Failed! Falsified (after 1 test)
```
What surprises me most is that the failing test has no apparent connection to the patch in question:
```haskell
, testProperty "fromString literal" $
fromString "\0\1\2\3\4" == B.pack [0,1,2,3,4]
```
See earlier discussion at https://github.com/haskell/bytestring/pull/394
CC @sjakobi @phadej9.0.2Matthew PickeringMatthew Pickering