GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2021-10-04T14:19:35Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/16810Use explicit lazy binding around undefined in inlinable functions2021-10-04T14:19:35Zkazu-yamamotoUse explicit lazy binding around undefined in inlinable functions# Summary
`undefined` in inlinable functions are unintentionally evaluated if called strictly. An example:
```
{-# INLINE alloca #-}
alloca :: forall a b . Storable a => (Ptr a -> IO b) -> IO b
alloca =
allocaBytesAligned (sizeOf (u...# Summary
`undefined` in inlinable functions are unintentionally evaluated if called strictly. An example:
```
{-# INLINE alloca #-}
alloca :: forall a b . Storable a => (Ptr a -> IO b) -> IO b
alloca =
allocaBytesAligned (sizeOf (undefined :: a)) (alignment (undefined :: a))
```
# Steps to reproduce
Use `Foreign.Marshal.Alloc.alloca` with `Strict` language extension.
# Expected behavior
It should allocate a memory, not evaluating `undefined`. If `undefined`s are used in inlinable functions, lazy bindings must be used explicitly for GHC 8.0 or later.
# Environment
* GHC version used: 8.0 or later
Optional:8.9https://gitlab.haskell.org/ghc/ghc/-/issues/16514Fix for #14619 is wrong2020-02-25T01:14:44ZDuane RyragFix for #14619 is wrongThe fix for #14619 is wrong. Please see https://gitlab.haskell.org/ghc/ghc/commit/add4e1f11b88cd603f6c01bc135eb576e1922a8e#note_190830.The fix for #14619 is wrong. Please see https://gitlab.haskell.org/ghc/ghc/commit/add4e1f11b88cd603f6c01bc135eb576e1922a8e#note_190830.8.6.5https://gitlab.haskell.org/ghc/ghc/-/issues/15730SCC/HPC/CORE annotation can change the meaning of an expression2020-01-02T20:44:54ZVladislav ZavialovSCC/HPC/CORE annotation can change the meaning of an expressionConsider this GHCi session:
```
Prelude> 1 / 2 / 2
0.25
Prelude> 1 / {-# SCC ann #-} 2 / 2
1.0
```
Adding an SCC annotation changed the meaning of the expression.
<details><summary>Trac metadata</summary>
| Trac field | V...Consider this GHCi session:
```
Prelude> 1 / 2 / 2
0.25
Prelude> 1 / {-# SCC ann #-} 2 / 2
1.0
```
Adding an SCC annotation changed the meaning of the expression.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------- |
| Version | 8.6.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler (Parser) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"SCC/HPC/CORE annotation can change the meaning of an expression","status":"New","operating_system":"","component":"Compiler (Parser)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider this GHCi session:\r\n\r\n{{{\r\nPrelude> 1 / 2 / 2\r\n0.25\r\nPrelude> 1 / {-# SCC ann #-} 2 / 2\r\n1.0\r\n}}}\r\n\r\nAdding an SCC annotation changed the meaning of the expression.","type_of_failure":"OtherFailure","blocking":[]} -->Vladislav ZavialovVladislav Zavialovhttps://gitlab.haskell.org/ghc/ghc/-/issues/14918GHC 8.4.1 regression: derived Read instances with field names containing # no...2019-07-07T18:15:03ZRyan ScottGHC 8.4.1 regression: derived Read instances with field names containing # no longer parse(Originally noticed [here](https://github.com/ekmett/transformers-compat/issues/32).)
Consider the following program:
```hs
{-# LANGUAGE MagicHash #-}
module Bug where
data T a = MkT { runT# :: a }
deriving (Read, Show)
t1, t2 :: T...(Originally noticed [here](https://github.com/ekmett/transformers-compat/issues/32).)
Consider the following program:
```hs
{-# LANGUAGE MagicHash #-}
module Bug where
data T a = MkT { runT# :: a }
deriving (Read, Show)
t1, t2 :: T Int
t1 = MkT 1
t2 = read $ show t1
main :: IO ()
main = print t2
```
In GHC 8.2.1, this runs without issue:
```
$ /opt/ghc/8.2.2/bin/runghc Bug.hs
MkT {runT# = 1}
```
In GHC 8.4.1, however, this produces a runtime error:
```
$ ~/Software/ghc-8.4.1/bin/runghc Bug.hs
Bug.hs: Prelude.read: no parse
```8.4.2https://gitlab.haskell.org/ghc/ghc/-/issues/14692Deriving Show with -XEmptyDataDeriving cases on the wrong argument2019-07-07T18:15:59ZRyan ScottDeriving Show with -XEmptyDataDeriving cases on the wrong argumentRunning this program in GHC 8.4.1-alpha:
```hs
{-# LANGUAGE EmptyDataDeriving #-}
{-# OPTIONS_GHC -ddump-deriv #-}
module Main (main) where
data Empty deriving Show
loop :: Empty
loop = let x = x in x
main :: IO ()
main = print loop
...Running this program in GHC 8.4.1-alpha:
```hs
{-# LANGUAGE EmptyDataDeriving #-}
{-# OPTIONS_GHC -ddump-deriv #-}
module Main (main) where
data Empty deriving Show
loop :: Empty
loop = let x = x in x
main :: IO ()
main = print loop
```
One would expect this to loop infinitely at runtime, but in practice, that is not the case:
```
$ /opt/ghc/8.4.1/bin/runghc Bug.hs
==================== Derived instances ====================
Derived class instances:
instance GHC.Show.Show Main.Empty where
GHC.Show.showsPrec z_a1Iu = case z_a1Iu of
Derived type family instances:
==================== Filling in method body ====================
GHC.Show.Show [Main.Empty]
GHC.Show.show = GHC.Show.$dmshow @(Main.Empty)
==================== Filling in method body ====================
GHC.Show.Show [Main.Empty]
GHC.Show.showList = GHC.Show.$dmshowList @(Main.Empty)
Bug.hs: Bug.hs:5:21-24: Non-exhaustive patterns in case
```
The `-ddump-deriv` output reveals why: the `showsPrec` implementation for `Empty` is casing on the //precedence// argument, not the actual value of type `Empty`! This results in the non-exhaustive patterns error.
This is my fault, so I'll prepare a fix :)
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.4.1-alpha1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Deriving Show with -XEmptyDataDeriving cases on the wrong argument","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.1-alpha1","keywords":["deriving"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Running this program in GHC 8.4.1-alpha:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE EmptyDataDeriving #-}\r\n{-# OPTIONS_GHC -ddump-deriv #-}\r\nmodule Main (main) where\r\n\r\ndata Empty deriving Show\r\n\r\nloop :: Empty\r\nloop = let x = x in x\r\n\r\nmain :: IO ()\r\nmain = print loop\r\n}}}\r\n\r\nOne would expect this to loop infinitely at runtime, but in practice, that is not the case:\r\n\r\n{{{\r\n$ /opt/ghc/8.4.1/bin/runghc Bug.hs\r\n\r\n==================== Derived instances ====================\r\nDerived class instances:\r\n instance GHC.Show.Show Main.Empty where\r\n GHC.Show.showsPrec z_a1Iu = case z_a1Iu of\r\n \r\n\r\nDerived type family instances:\r\n\r\n\r\n\r\n==================== Filling in method body ====================\r\nGHC.Show.Show [Main.Empty]\r\n GHC.Show.show = GHC.Show.$dmshow @(Main.Empty)\r\n\r\n\r\n\r\n==================== Filling in method body ====================\r\nGHC.Show.Show [Main.Empty]\r\n GHC.Show.showList = GHC.Show.$dmshowList @(Main.Empty)\r\n\r\n\r\nBug.hs: Bug.hs:5:21-24: Non-exhaustive patterns in case\r\n}}}\r\n\r\nThe `-ddump-deriv` output reveals why: the `showsPrec` implementation for `Empty` is casing on the //precedence// argument, not the actual value of type `Empty`! This results in the non-exhaustive patterns error.\r\n\r\nThis is my fault, so I'll prepare a fix :)","type_of_failure":"OtherFailure","blocking":[]} -->8.4.1https://gitlab.haskell.org/ghc/ghc/-/issues/14646GHC 8.4.1 regression: rank-n types no longer parenthesized when pretty-printed2019-07-07T18:16:10ZRyan ScottGHC 8.4.1 regression: rank-n types no longer parenthesized when pretty-printedTake this file:
```hs
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -ddump-splices #-}
module Bug where
import Language.Haskell.TH
$([d| f :: (forall a. a) -> Int
f _ = undefined |])
```
In GHC 8....Take this file:
```hs
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# OPTIONS_GHC -ddump-splices #-}
module Bug where
import Language.Haskell.TH
$([d| f :: (forall a. a) -> Int
f _ = undefined |])
```
In GHC 8.2.2, `-ddump-splices` behaves as you'd expect:
```
$ /opt/ghc/8.2.2/bin/ghci Bug.hs
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Bug ( Bug.hs, interpreted )
Bug.hs:(8,3)-(9,24): Splicing declarations
[d| f_a1zL :: (forall a_a1zM. a_a1zM) -> Int
f_a1zL _ = undefined |]
======>
f_a49Z :: (forall a_a4a0. a_a4a0) -> Int
f_a49Z _ = undefined
Ok, one module loaded.
```
But in GHC 8.4.1-alpha (and HEAD), the GHC pretty-printer incorrectly leaves off the parentheses around the type `(forall a. a)`:
```
$ /opt/ghc/8.4.1/bin/ghci Bug.hs
GHCi, version 8.4.0.20171222: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Bug ( Bug.hs, interpreted )
Bug.hs:(8,3)-(9,24): Splicing declarations
[d| f_a1EF :: (forall a_a1EG. a_a1EG) -> Int
f_a1EF _ = undefined |]
======>
f_a4ap :: forall a_a4aq. a_a4aq -> Int
f_a4ap _ = undefined
Ok, one module loaded.
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.4.1-alpha1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | GHC API |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | alanz |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC 8.4.1 regression: rank-n types no longer parenthesized when pretty-printed","status":"New","operating_system":"","component":"GHC API","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.1-alpha1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["alanz"],"type":"Bug","description":"Take this file:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE RankNTypes #-}\r\n{-# LANGUAGE TemplateHaskell #-}\r\n{-# OPTIONS_GHC -ddump-splices #-}\r\nmodule Bug where\r\n\r\nimport Language.Haskell.TH\r\n\r\n$([d| f :: (forall a. a) -> Int\r\n f _ = undefined |])\r\n}}}\r\n\r\nIn GHC 8.2.2, `-ddump-splices` behaves as you'd expect:\r\n\r\n{{{\r\n$ /opt/ghc/8.2.2/bin/ghci Bug.hs\r\nGHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help\r\nLoaded GHCi configuration from /home/rgscott/.ghci\r\n[1 of 1] Compiling Bug ( Bug.hs, interpreted )\r\nBug.hs:(8,3)-(9,24): Splicing declarations\r\n [d| f_a1zL :: (forall a_a1zM. a_a1zM) -> Int\r\n f_a1zL _ = undefined |]\r\n ======>\r\n f_a49Z :: (forall a_a4a0. a_a4a0) -> Int\r\n f_a49Z _ = undefined\r\nOk, one module loaded.\r\n}}}\r\n\r\nBut in GHC 8.4.1-alpha (and HEAD), the GHC pretty-printer incorrectly leaves off the parentheses around the type `(forall a. a)`:\r\n\r\n{{{\r\n$ /opt/ghc/8.4.1/bin/ghci Bug.hs\r\nGHCi, version 8.4.0.20171222: http://www.haskell.org/ghc/ :? for help\r\nLoaded GHCi configuration from /home/rgscott/.ghci\r\n[1 of 1] Compiling Bug ( Bug.hs, interpreted )\r\nBug.hs:(8,3)-(9,24): Splicing declarations\r\n [d| f_a1EF :: (forall a_a1EG. a_a1EG) -> Int\r\n f_a1EF _ = undefined |]\r\n ======>\r\n f_a4ap :: forall a_a4aq. a_a4aq -> Int\r\n f_a4ap _ = undefined\r\nOk, one module loaded.\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.4.1Ryan ScottRyan Scotthttps://gitlab.haskell.org/ghc/ghc/-/issues/14521Infinite loop at runtime2019-07-07T18:16:41ZOlivierSohnInfinite loop at runtimeHello,
For this program : https://github.com/OlivierSohn/hamazed/tree/repro-ghc-14521-A
The expected output is:
```
Before rendering animations
animation is rendered
After rendering animations
```
What I observe is when compiling wit...Hello,
For this program : https://github.com/OlivierSohn/hamazed/tree/repro-ghc-14521-A
The expected output is:
```
Before rendering animations
animation is rendered
After rendering animations
```
What I observe is when compiling with ghc 8.0.2 or 8.2.2, with optimizations:
```
Before rendering animations
```
I found several ways to circumvent the bug, and documented each one in the source code.
Can someone take a look? Is my program an invalid program that was not detected by the compiler?
Thank you,
Olivier8.2.3https://gitlab.haskell.org/ghc/ghc/-/issues/14434GHC 8.2.1 picks wrong instances with -O in a presence of an OVERLAPPABLE inst...2019-07-07T18:17:03ZdredozubovGHC 8.2.1 picks wrong instances with -O in a presence of an OVERLAPPABLE instanceWe experienced code breakage while moving to 8.2.1 - in some circumstances it picks wrong instances if an instance in the lines of `instance {-# OVERLAPPABLE #-} C a ` is defined. \@s9gf4ult was really nice to create a repo demonstrating...We experienced code breakage while moving to 8.2.1 - in some circumstances it picks wrong instances if an instance in the lines of `instance {-# OVERLAPPABLE #-} C a ` is defined. \@s9gf4ult was really nice to create a repo demonstrating an issue, you can look at the repo here: [https://github.com/s9gf4ult/isogen-minimal-example](https://github.com/s9gf4ult/isogen-minimal-example)
Running `chech.sh` will trigger three builds:
```
GHC 8.0.2, -O, succeeds
GHC 8.2.1, -O0, succeeds
GHC 8.2.1, -O, fails
```
If you'll check out to either of fix- branches:
```
fix-move-to_string
fix-no-catchall-instance
fix-replace-to_string
fix-add-irrelevant-instance
```
then the last test should succeed also. Those branches contain changes over master which fix the application behavior in different ways.8.4.1https://gitlab.haskell.org/ghc/ghc/-/issues/14361GHC HEAD miscompiles `text-containers`2019-07-07T18:17:19ZHerbert Valerio Riedelhvr@gnu.orgGHC HEAD miscompiles `text-containers`When compiling and running `text-containers`'s test-suite, the test-cases involving lookup functions (e.g. `member :: Key -> TextSet -> Bool`) fail indeterministically.
NB: The code in question works perfectly for GHC 7.10.3/8.0.2/8.2.1...When compiling and running `text-containers`'s test-suite, the test-cases involving lookup functions (e.g. `member :: Key -> TextSet -> Bool`) fail indeterministically.
NB: The code in question works perfectly for GHC 7.10.3/8.0.2/8.2.1; and I've also verified this isn't related to the new `compareByteArray#` primop; in fact you get the very same failures if you force `text-containers` to use the memcmp FFI (by editing the respective `if` conditional in the .cabal file).
Repro instructions (sorry, haven't had time to minimize it yet):
```sh
# get wip/ghc-T14361 branch of `text-containers`
git clone https://github.com/hvr/text-containers.git -b wip/ghc-T14361
cd text-containers/
# generate cabal.project.local
cat > cabal.project.local <<EOF
repository head.hackage
url: http://head.hackage.haskell.org/
secure: True
root-keys: 07c59cb65787dedfaef5bd5f987ceb5f7e5ebf88b904bbd4c5cbdeb2ff71b740
2e8555dde16ebd8df076f1a8ef13b8f14c66bad8eafefd7d9e37d0ed711821fb
8f79fd2389ab2967354407ec852cbe73f2e8635793ac446d09461ffb99527f6e
key-threshold: 3
allow-newer: *:base, tagged-0.8.5:template-haskell
EOF
# update head.hackage package index if needed;
# use https://github.com/hvr/head.hackage/blob/master/scripts/head.hackage.sh script
head.hackage.sh update
```
You can now build & run the test-suite via (if you need, you can replace `ghc-8.3.20171016` by the full path to your `inplace/bin/ghc-stage2` executable):
```
cabal new-test -w ghc-8.3.20171016
```
1. ..and this will report
```
...
All 44 tests passed (3.81s)
Test suite text-containers: PASS
Test suite logged to:
dist-newstyle/build/x86_64-linux/ghc-8.3.20171016/text-containers-0.1.0.0/t/text-containers/test/text-containers-0.1.0.0-text-containers.log
1 of 1 test suites (1 of 1 test cases) passed.
```
If however, you edit `src/Internal2.hs` and disable either the
- `{-# OPTIONS_GHC -fno-strictness #-}` or the
- `{-# NOINLINE cmpBA2OfsLen #-}`
pragmas, and re-run the test-suite, those 6 of the 44 tests which test the `member`/`lookup{GE,LE}` operations will start failing, e.g.
```
...
null: OK (0.06s)
+++ OK, passed 100 tests.
member: FAIL
*** Failed! Falsifiable (after 25 tests and 6 shrinks):
Ps [("\74914\869082\952045\187526\US",18),("\444739R^\DC3\RSpr",-20),("Je\5900LfM\SI\622028\13867\861002\\+?\49284Mi",9),("\ETB",-3),("\EOT,3/{wdirM\66595\829945R\17707_9\1079715DA\SOH5",0),("Md",-13),("gSY\ESC3N\DLEE\864876'~\184683z\ESCy<\r\448917\787640\SYN\752866",15)]
Use --quickcheck-replay=592157 to reproduce.
(!?): FAIL
*** Failed! Falsifiable (after 18 tests and 2 shrinks):
Ps [("\DC3|X|\488551)|8\NAKa\278082an\649221\v\843318",1),("\603109\SYN\EOT\999535<M%\USBXEu\734582",0),("C\625018.",-7),("iV\ESCu",-16),("d\aJ7@\DLE2\102734\a\868938",8),("i\974801rl\1094305b[\ESC\a?",-5),("\95327[hB",1),("rG\v\1017578\CAN\ACK",-6)]
Use --quickcheck-replay=713273 to reproduce.
TextSet
toList.fromList: OK (0.07s)
+++ OK, passed 100 tests.
...
6 out of 44 tests failed (3.20s)
Test suite text-containers: FAIL
Test suite logged to:
dist-newstyle/build/x86_64-linux/ghc-8.3.20171016/text-containers-0.1.0.0/t/text-containers/test/text-containers-0.1.0.0-text-containers.log
0 of 1 test suites (0 of 1 test cases) passed.
cabal: Tests failed for test:text-containers from text-containers-0.1.0.0.
```
And you'll notice that even if `--quickcheck-replay` is used, the failures will not be 100% deterministic.8.4.1https://gitlab.haskell.org/ghc/ghc/-/issues/13425Semantically-equivalent expressions evaluating at different values with -O12019-07-07T18:21:55ZrbassoSemantically-equivalent expressions evaluating at different values with -O1The following code shows inconsistent results when compiled with -O1:
```hs
import Data.Bits ((.&.))
flags :: Int -> [Int]
flags x = filter (\y -> x .&. y > 0) [1, 128, 129, 255]
main :: IO ()
main = do
putStrLn $ show $ flags $ 255...The following code shows inconsistent results when compiled with -O1:
```hs
import Data.Bits ((.&.))
flags :: Int -> [Int]
flags x = filter (\y -> x .&. y > 0) [1, 128, 129, 255]
main :: IO ()
main = do
putStrLn $ show $ flags $ 255 -- These lines should display
putStrLn (show (flags 255)) -- the same value, right?
-- It appears that this is related to something that started
-- with GHC 7.10, but was also changed in GHC 8.0, as we can
-- see from the following tests:
--
-- Stack snapshot lts-0.7 (GHC 7.8.3), with -O2
-- [1,128,129,255]
-- [1,128,129,255]
--
-- Stack snapshot lts-2.22 (GHC 7.8.4) with -O2
-- [1,128,129,255]
-- [1,128,129,255]
--
-- Stack snapshot lts-3.22 (GHC 7.10.2) with -O2
-- [1]
-- [1]
--
-- Stack snapshot lts-6.30 (GHC 7.10.3) with -O2
-- [1]
-- [1]
--
-- Stack snapshot lts-7.20 (GHC 8.0.1) with -O2
-- [1]
-- [1,128,129,255]
--
-- Stack snapshot lts-8.5 (GHC 8.0.2) with -O2
-- [1]
-- [1,128,129,255]
--
-- In GHC 8.0.2, compiling with any of the following...
-- -O0
-- -O2 -fno-cmm-sink
-- -O2 -fno-enable-rewrite-rules
--
-- ...we get the expected results:
-- [1,128,129,255]
-- [1,128,129,255]
--
-- Using only -O1, we get the abnormal behavior again:
-- [1]
-- [1,128,129,255]
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.0.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Semantically-equivalent expressions evaluating at different values with -O1","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The following code shows inconsistent results when compiled with -O1:\r\n\r\n{{{#!hs\r\nimport Data.Bits ((.&.))\r\n\r\nflags :: Int -> [Int]\r\nflags x = filter (\\y -> x .&. y > 0) [1, 128, 129, 255]\r\n\r\nmain :: IO ()\r\nmain = do\r\n putStrLn $ show $ flags $ 255 -- These lines should display\r\n putStrLn (show (flags 255)) -- the same value, right?\r\n\r\n-- It appears that this is related to something that started\r\n-- with GHC 7.10, but was also changed in GHC 8.0, as we can\r\n-- see from the following tests:\r\n--\r\n-- Stack snapshot lts-0.7 (GHC 7.8.3), with -O2\r\n-- [1,128,129,255]\r\n-- [1,128,129,255]\r\n--\r\n-- Stack snapshot lts-2.22 (GHC 7.8.4) with -O2\r\n-- [1,128,129,255]\r\n-- [1,128,129,255]\r\n--\r\n-- Stack snapshot lts-3.22 (GHC 7.10.2) with -O2\r\n-- [1]\r\n-- [1]\r\n--\r\n-- Stack snapshot lts-6.30 (GHC 7.10.3) with -O2\r\n-- [1]\r\n-- [1]\r\n--\r\n-- Stack snapshot lts-7.20 (GHC 8.0.1) with -O2\r\n-- [1]\r\n-- [1,128,129,255]\r\n--\r\n-- Stack snapshot lts-8.5 (GHC 8.0.2) with -O2\r\n-- [1]\r\n-- [1,128,129,255]\r\n--\r\n-- In GHC 8.0.2, compiling with any of the following...\r\n-- -O0\r\n-- -O2 -fno-cmm-sink\r\n-- -O2 -fno-enable-rewrite-rules\r\n--\r\n-- ...we get the expected results:\r\n-- [1,128,129,255]\r\n-- [1,128,129,255]\r\n--\r\n-- Using only -O1, we get the abnormal behavior again:\r\n-- [1]\r\n-- [1,128,129,255]\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.2.1https://gitlab.haskell.org/ghc/ghc/-/issues/13203Implement Bits Natural clearBit2019-07-07T18:23:12Zdylan@dylex.netImplement Bits Natural clearBitThe current Bits Natural implementation says:
`TODO: setBit, clearBit, complementBit (needs more primitives)`.
The default implementations of setBit and complementBit work fine, but clearBit relies on complement, and so fails. Even if it...The current Bits Natural implementation says:
`TODO: setBit, clearBit, complementBit (needs more primitives)`.
The default implementations of setBit and complementBit work fine, but clearBit relies on complement, and so fails. Even if it had to use a conditional complementBit on testBit, it would be better than nothing.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.0.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | libraries/base |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Implement Bits Natural clearBit","status":"New","operating_system":"","component":"libraries/base","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The current Bits Natural implementation says:\r\n{{{TODO: setBit, clearBit, complementBit (needs more primitives)}}}.\r\nThe default implementations of setBit and complementBit work fine, but clearBit relies on complement, and so fails. Even if it had to use a conditional complementBit on testBit, it would be better than nothing.","type_of_failure":"OtherFailure","blocking":[]} -->8.2.2Sven TennieSven Tenniehttps://gitlab.haskell.org/ghc/ghc/-/issues/12614Integer division can overwrite other arguments to foreign call2019-07-07T18:25:50ZjschollInteger division can overwrite other arguments to foreign callIf you call a foreign function, GHC can generate incorrect code while passing the arguments to the function, overwriting the 3rd argument if a later argument contains an integer division.
Main.hs:
```
{-# LANGUAGE ForeignFunctionInterf...If you call a foreign function, GHC can generate incorrect code while passing the arguments to the function, overwriting the 3rd argument if a later argument contains an integer division.
Main.hs:
```
{-# LANGUAGE ForeignFunctionInterface #-}
module Main where
{-# NOINLINE foo #-}
foo :: Int -> IO ()
foo x = c_foo 0 0 x $ x + x `quot` 10
foreign import ccall "foo" c_foo :: Int -> Int -> Int -> Int -> IO ()
main :: IO ()
main = do
foo 202
foo 203
foo 204
```
foo.c:
```
#include <stdio.h>
void foo(int a, int b, int c, int d) {
printf("%d, %d, %d, %d\n", a, b, c, d);
}
```
Expected output:
```
0, 0, 202, 222
0, 0, 203, 223
0, 0, 204, 224
```
Actual output:
```
0, 0, 2, 222
0, 0, 3, 223
0, 0, 4, 224
```
The bug has to be somewhere in the code generator. The cmm reads:
```
call "ccall" arg hints: [‘signed’, ‘signed’, ‘signed’, ‘signed’] result hints: [] foo(0, 0, _s3nE::I64, _s3nE::I64 + %MO_S_Quot_W64(_s3nE::I64, 10));
```
This generates the following assembler code:
```
xorl %edi,%edi
xorl %esi,%esi
movq %rbx,%rdx
movl $10,%ecx
movq %rax,%rdx <-- move 3rd argument into rdx
movq %rbx,%rax
movq %rdx,%r8
cqto
idivq %rcx <-- rax := rax / rcx; rdx := rax % rcx
movq %rbx,%rcx
addq %rax,%rcx
subq $8,%rsp
xorl %eax,%eax
movq %r8,%rbx
call foo
```
Thus rdx is overwritten again before the call, leading to incorrect results.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.0.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (NCG) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Integer division can overwrite other arguments to foreign call","status":"New","operating_system":"","component":"Compiler (NCG)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":["division","integer"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"If you call a foreign function, GHC can generate incorrect code while passing the arguments to the function, overwriting the 3rd argument if a later argument contains an integer division.\r\n\r\nMain.hs:\r\n\r\n{{{\r\n{-# LANGUAGE ForeignFunctionInterface #-}\r\nmodule Main where\r\n\r\n{-# NOINLINE foo #-}\r\nfoo :: Int -> IO ()\r\nfoo x = c_foo 0 0 x $ x + x `quot` 10\r\n\r\nforeign import ccall \"foo\" c_foo :: Int -> Int -> Int -> Int -> IO ()\r\n\r\nmain :: IO ()\r\nmain = do\r\n foo 202\r\n foo 203\r\n foo 204\r\n}}}\r\n\r\nfoo.c:\r\n\r\n{{{\r\n#include <stdio.h>\r\n\r\nvoid foo(int a, int b, int c, int d) {\r\n printf(\"%d, %d, %d, %d\\n\", a, b, c, d);\r\n}\r\n}}}\r\n\r\nExpected output:\r\n{{{\r\n0, 0, 202, 222\r\n0, 0, 203, 223\r\n0, 0, 204, 224\r\n}}}\r\n\r\nActual output:\r\n{{{\r\n0, 0, 2, 222\r\n0, 0, 3, 223\r\n0, 0, 4, 224\r\n}}}\r\n\r\nThe bug has to be somewhere in the code generator. The cmm reads:\r\n\r\n{{{\r\ncall \"ccall\" arg hints: [‘signed’, ‘signed’, ‘signed’, ‘signed’] result hints: [] foo(0, 0, _s3nE::I64, _s3nE::I64 + %MO_S_Quot_W64(_s3nE::I64, 10));\r\n}}}\r\n\r\nThis generates the following assembler code:\r\n\r\n{{{\r\n xorl %edi,%edi\r\n xorl %esi,%esi\r\n movq %rbx,%rdx\r\n movl $10,%ecx\r\n movq %rax,%rdx <-- move 3rd argument into rdx\r\n movq %rbx,%rax\r\n movq %rdx,%r8\r\n cqto\r\n idivq %rcx <-- rax := rax / rcx; rdx := rax % rcx\r\n movq %rbx,%rcx\r\n addq %rax,%rcx\r\n subq $8,%rsp\r\n xorl %eax,%eax\r\n movq %r8,%rbx\r\n call foo\r\n}}}\r\n\r\nThus rdx is overwritten again before the call, leading to incorrect results.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.2https://gitlab.haskell.org/ghc/ghc/-/issues/12095GHC and LLVM don't agree on what to do with byteSwap16#2020-01-06T17:32:27ZthoughtpoliceGHC and LLVM don't agree on what to do with byteSwap16#Consider this test case (taken from [here](https://github.com/well-typed/binary-serialise-cbor/issues/67) and lightly modified to work on big/little endian machines):
```hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-#...Consider this test case (taken from [here](https://github.com/well-typed/binary-serialise-cbor/issues/67) and lightly modified to work on big/little endian machines):
```hs
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE CPP #-}
module Main
( main -- :: IO ()
) where
#include "ghcconfig.h"
import GHC.Prim
import GHC.Word
data T = T !Addr#
t :: T
#ifndef WORDS_BIGENDIAN
t = T "\xcf\xb1"#
#else
t = T "\xb1\xcf"#
#endif
grabWord16 :: T -> Word64
grabWord16 (T addr#) = W64# (byteSwap16# (indexWord16OffAddr# addr# 0#))
trip :: Int
trip = fromIntegral (grabWord16 t)
main :: IO ()
main = print trip
```
With GHC 7.10.3 using the NCG, the results given are correct:
```
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.10.3
$ ghc -Wall -fforce-recomp -O2 Issue67.hs && ./Issue67
[1 of 1] Compiling Main ( Issue67.hs, Issue67.o )
Linking Issue67 ...
53169
```
This also is the same on GHC 8.0.1 using the NCG, on both PowerPC and AMD64 as well. This answer is correct: `53169` is `0xCFB1` in hex, so the `byteSwap16#` primitive correctly works to decode the swapped-endian number.
However, the story is not the same with GHC 7.10.3+LLVM 3.5, or GHC 8.0.1+LLVM 3.7:
```
$ 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 -Wall -fforce-recomp -O2 Issue67.hs -fllvm && ./Issue67
[1 of 1] Compiling Main ( Issue67.hs, Issue67.o )
Linking Issue67 ...
-12367
```
Note:
```hs
-12367 == (fromIntegral (53169 :: Word16) :: Int16)
```
The relevant snippet looks like this at the CMM level (GHC 7.10.3):
```
==================== Output Cmm ====================
[section "data" {
Main.main2_closure:
const Main.main2_info;
const 0;
const 0;
const 0;
},
section "readonly" {
c3rq_str:
I8[] [207,177]
},
section "readonly" {
c3rr_str:
I8[] [207,177]
},
Main.main2_entry() // [R1]
{ info_tbl: [(c3ru,
label: Main.main2_info
rep:HeapRep static { Thunk }),
(c3rD,
label: block_c3rD_info
rep:StackRep [])]
stack_info: arg_space: 8 updfr_space: Just 8
}
{offset
c3ru:
...
c3ro:
I64[Sp - 16] = stg_bh_upd_frame_info;
I64[Sp - 8] = _c3rn::I64;
(_c3rw::I64) = call MO_BSwap W16(%MO_UU_Conv_W16_W64(I16[c3rr_str]));
I64[Sp - 24] = c3rD;
R4 = GHC.Types.[]_closure+1;
R3 = _c3rw::I64;
R2 = 0;
Sp = Sp - 24;
call GHC.Show.$wshowSignedInt_info(R4,
R3,
R2) returns to c3rD, args: 8, res: 8, upd: 24;
...
```
Pre-optimized LLVM basic block:
```
c3rB:
%ln3sc = ptrtoint i8* @stg_bh_upd_frame_info to i64
%ln3sb = load i64** %Sp_Var
%ln3sd = getelementptr inbounds i64* %ln3sb, i32 -2
store i64 %ln3sc, i64* %ln3sd, !tbaa !1
%ln3sf = load i64* %lc3rA
%ln3se = load i64** %Sp_Var
%ln3sg = getelementptr inbounds i64* %ln3se, i32 -1
store i64 %ln3sf, i64* %ln3sg, !tbaa !1
%ln3sh = ptrtoint %c3rE_str_struct* @c3rE_str$def to i64
%ln3si = inttoptr i64 %ln3sh to i16*
%ln3sj = load i16* %ln3si, !tbaa !5
%ln3sk = zext i16 %ln3sj to i64
%ln3sl = trunc i64 %ln3sk to i16
%ln3sm = call ccc i16 (i16)* @llvm.bswap.i16( i16 %ln3sl )
%ln3sn = sext i16 %ln3sm to i64
store i64 %ln3sn, i64* %lc3rJ
%ln3sp = ptrtoint void (i64*, i64*, i64*, i64, i64, i64, i64, i64, i64, i64)* @c3rQ_info$def to i64
%ln3so = load i64** %Sp_Var
%ln3sq = getelementptr inbounds i64* %ln3so, i32 -3
store i64 %ln3sp, i64* %ln3sq, !tbaa !1
%ln3sr = ptrtoint i8* @ghczmprim_GHCziTypes_ZMZN_closure to i64
%ln3ss = add i64 %ln3sr, 1
store i64 %ln3ss, i64* %R4_Var
%ln3st = load i64* %lc3rJ
store i64 %ln3st, i64* %R3_Var
store i64 0, i64* %R2_Var
%ln3su = load i64** %Sp_Var
%ln3sv = getelementptr inbounds i64* %ln3su, i32 -3
%ln3sw = ptrtoint i64* %ln3sv to i64
%ln3sx = inttoptr i64 %ln3sw to i64*
store i64* %ln3sx, i64** %Sp_Var
%ln3sy = bitcast i8* @base_GHCziShow_zdwshowSignedInt_info to void (i64*, i64*, i64*, i64, i64, i64, i64, i64, i64, i64)*
```
Post-optimized block (`opt --enable-tbaa=true -O2 out-llvm-orig.ll -o out-llvm.bc`):
```
c3rB: ; preds = %c3rU
%ln3s8 = ptrtoint i8* %ln3s7 to i64
%ln3sd = getelementptr inbounds i64* %Sp_Arg, i64 -2
store i64 ptrtoint (i8* @stg_bh_upd_frame_info to i64), i64* %ln3sd, align 8, !tbaa !5
%ln3sg = getelementptr inbounds i64* %Sp_Arg, i64 -1
store i64 %ln3s8, i64* %ln3sg, align 8, !tbaa !5
store i64 ptrtoint (void (i64*, i64*, i64*, i64, i64, i64, i64, i64, i64, i64)* @"c3rQ_info$def" to i64), i64* %ln3rZ, align 8, !tbaa !5
tail call cc10 void bitcast (i8* @base_GHCziShow_zdwshowSignedInt_info to void (i64*, i64*, i64*, i64, i64, i64, i64, i64, i64, i64)*)(i64* %Base_Arg, i64* %ln3rZ, i64* %Hp_Arg, i64 %R1_Arg, i64 0, i64 -12367, i64 add (i64 ptrtoint (i8* @ghczmprim_GHCziTypes_ZMZN_closure to i64), i64 1), i64 undef, i64 undef, i64 %SpLim_Arg) #0
ret void
```
Folds it right into a constant!
I haven't spent time diagnosing this much further, yet.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | --------------- |
| Version | 8.0.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler (LLVM) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC and LLVM don't agree on what to do with byteSwap16#","status":"New","operating_system":"","component":"Compiler (LLVM)","related":[],"milestone":"8.0.2","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":["codegen,","llvm"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider this test case (taken from [https://github.com/well-typed/binary-serialise-cbor/issues/67 here] and lightly modified to work on big/little endian machines):\r\n\r\n{{{#!hs\r\n{-# LANGUAGE BangPatterns #-}\r\n{-# LANGUAGE MagicHash #-}\r\n{-# LANGUAGE CPP #-}\r\nmodule Main\r\n ( main -- :: IO ()\r\n ) where\r\n\r\n#include \"ghcconfig.h\"\r\n\r\nimport GHC.Prim\r\nimport GHC.Word\r\n\r\ndata T = T !Addr#\r\n\r\nt :: T\r\n#ifndef WORDS_BIGENDIAN\r\nt = T \"\\xcf\\xb1\"#\r\n#else\r\nt = T \"\\xb1\\xcf\"#\r\n#endif\r\n\r\ngrabWord16 :: T -> Word64\r\ngrabWord16 (T addr#) = W64# (byteSwap16# (indexWord16OffAddr# addr# 0#))\r\n\r\ntrip :: Int\r\ntrip = fromIntegral (grabWord16 t)\r\n\r\nmain :: IO ()\r\nmain = print trip\r\n}}}\r\n\r\nWith GHC 7.10.3 using the NCG, the results given are correct:\r\n\r\n{{{\r\n$ ghc --version\r\nThe Glorious Glasgow Haskell Compilation System, version 7.10.3\r\n$ ghc -Wall -fforce-recomp -O2 Issue67.hs && ./Issue67\r\n[1 of 1] Compiling Main ( Issue67.hs, Issue67.o )\r\nLinking Issue67 ...\r\n53169\r\n}}}\r\n\r\nThis also is the same on GHC 8.0.1 using the NCG, on both PowerPC and AMD64 as well. This answer is correct: `53169` is `0xCFB1` in hex, so the `byteSwap16#` primitive correctly works to decode the swapped-endian number.\r\n\r\nHowever, the story is not the same with GHC 7.10.3+LLVM 3.5, or GHC 8.0.1+LLVM 3.7:\r\n\r\n{{{\r\n$ ghc --version\r\nThe Glorious Glasgow Haskell Compilation System, version 7.10.3\r\n$ llc --version | head -2\r\nLLVM (http://llvm.org/):\r\n LLVM version 3.5.2\r\n$ ghc -Wall -fforce-recomp -O2 Issue67.hs -fllvm && ./Issue67\r\n[1 of 1] Compiling Main ( Issue67.hs, Issue67.o )\r\nLinking Issue67 ...\r\n-12367\r\n}}}\r\n\r\nNote:\r\n\r\n{{{#!hs\r\n-12367 == (fromIntegral (53169 :: Word16) :: Int16)\r\n}}}\r\n\r\nThe relevant snippet looks like this at the CMM level (GHC 7.10.3):\r\n\r\n{{{\r\n==================== Output Cmm ====================\r\n[section \"data\" {\r\n Main.main2_closure:\r\n const Main.main2_info;\r\n const 0;\r\n const 0;\r\n const 0;\r\n },\r\n section \"readonly\" {\r\n c3rq_str:\r\n I8[] [207,177]\r\n },\r\n section \"readonly\" {\r\n c3rr_str:\r\n I8[] [207,177]\r\n },\r\n Main.main2_entry() // [R1]\r\n { info_tbl: [(c3ru,\r\n label: Main.main2_info\r\n rep:HeapRep static { Thunk }),\r\n (c3rD,\r\n label: block_c3rD_info\r\n rep:StackRep [])]\r\n stack_info: arg_space: 8 updfr_space: Just 8\r\n }\r\n {offset\r\n c3ru:\r\n ...\r\n c3ro:\r\n I64[Sp - 16] = stg_bh_upd_frame_info;\r\n I64[Sp - 8] = _c3rn::I64;\r\n (_c3rw::I64) = call MO_BSwap W16(%MO_UU_Conv_W16_W64(I16[c3rr_str]));\r\n I64[Sp - 24] = c3rD;\r\n R4 = GHC.Types.[]_closure+1;\r\n R3 = _c3rw::I64;\r\n R2 = 0;\r\n Sp = Sp - 24;\r\n call GHC.Show.$wshowSignedInt_info(R4,\r\n R3,\r\n R2) returns to c3rD, args: 8, res: 8, upd: 24;\r\n...\r\n}}}\r\n\r\nPre-optimized LLVM basic block:\r\n\r\n{{{\r\nc3rB:\r\n %ln3sc = ptrtoint i8* @stg_bh_upd_frame_info to i64\r\n %ln3sb = load i64** %Sp_Var\r\n %ln3sd = getelementptr inbounds i64* %ln3sb, i32 -2\r\n store i64 %ln3sc, i64* %ln3sd, !tbaa !1\r\n %ln3sf = load i64* %lc3rA\r\n %ln3se = load i64** %Sp_Var\r\n %ln3sg = getelementptr inbounds i64* %ln3se, i32 -1\r\n store i64 %ln3sf, i64* %ln3sg, !tbaa !1\r\n %ln3sh = ptrtoint %c3rE_str_struct* @c3rE_str$def to i64\r\n %ln3si = inttoptr i64 %ln3sh to i16*\r\n %ln3sj = load i16* %ln3si, !tbaa !5\r\n %ln3sk = zext i16 %ln3sj to i64\r\n %ln3sl = trunc i64 %ln3sk to i16\r\n %ln3sm = call ccc i16 (i16)* @llvm.bswap.i16( i16 %ln3sl )\r\n %ln3sn = sext i16 %ln3sm to i64\r\n store i64 %ln3sn, i64* %lc3rJ\r\n %ln3sp = ptrtoint void (i64*, i64*, i64*, i64, i64, i64, i64, i64, i64, i64)* @c3rQ_info$def to i64\r\n %ln3so = load i64** %Sp_Var\r\n %ln3sq = getelementptr inbounds i64* %ln3so, i32 -3\r\n store i64 %ln3sp, i64* %ln3sq, !tbaa !1\r\n %ln3sr = ptrtoint i8* @ghczmprim_GHCziTypes_ZMZN_closure to i64\r\n %ln3ss = add i64 %ln3sr, 1\r\n store i64 %ln3ss, i64* %R4_Var\r\n %ln3st = load i64* %lc3rJ\r\n store i64 %ln3st, i64* %R3_Var\r\n store i64 0, i64* %R2_Var\r\n %ln3su = load i64** %Sp_Var\r\n %ln3sv = getelementptr inbounds i64* %ln3su, i32 -3\r\n %ln3sw = ptrtoint i64* %ln3sv to i64\r\n %ln3sx = inttoptr i64 %ln3sw to i64*\r\n store i64* %ln3sx, i64** %Sp_Var\r\n %ln3sy = bitcast i8* @base_GHCziShow_zdwshowSignedInt_info to void (i64*, i64*, i64*, i64, i64, i64, i64, i64, i64, i64)*\r\n}}}\r\n\r\nPost-optimized block (`opt --enable-tbaa=true -O2 out-llvm-orig.ll -o out-llvm.bc`):\r\n\r\n{{{\r\nc3rB: ; preds = %c3rU\r\n %ln3s8 = ptrtoint i8* %ln3s7 to i64\r\n %ln3sd = getelementptr inbounds i64* %Sp_Arg, i64 -2\r\n store i64 ptrtoint (i8* @stg_bh_upd_frame_info to i64), i64* %ln3sd, align 8, !tbaa !5\r\n %ln3sg = getelementptr inbounds i64* %Sp_Arg, i64 -1\r\n store i64 %ln3s8, i64* %ln3sg, align 8, !tbaa !5\r\n store i64 ptrtoint (void (i64*, i64*, i64*, i64, i64, i64, i64, i64, i64, i64)* @\"c3rQ_info$def\" to i64), i64* %ln3rZ, align 8, !tbaa !5\r\n tail call cc10 void bitcast (i8* @base_GHCziShow_zdwshowSignedInt_info to void (i64*, i64*, i64*, i64, i64, i64, i64, i64, i64, i64)*)(i64* %Base_Arg, i64* %ln3rZ, i64* %Hp_Arg, i64 %R1_Arg, i64 0, i64 -12367, i64 add (i64 ptrtoint (i8* @ghczmprim_GHCziTypes_ZMZN_closure to i64), i64 1), i64 undef, i64 undef, i64 %SpLim_Arg) #0\r\n ret void\r\n}}}\r\n\r\nFolds it right into a constant!\r\n\r\nI haven't spent time diagnosing this much further, yet.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.2https://gitlab.haskell.org/ghc/ghc/-/issues/11792Optimised unsafe FFI call can get wrong argument2019-07-07T18:28:31ZSzuntiOptimised unsafe FFI call can get wrong argumentAttached a simple test case. It should print 7457, but the C function is called with 0 as the third argument.
If I compile with -O0 or omit the unsafe keyword in the FFI import it works as it should.
In gdb disassembly looks to me as e...Attached a simple test case. It should print 7457, but the C function is called with 0 as the third argument.
If I compile with -O0 or omit the unsafe keyword in the FFI import it works as it should.
In gdb disassembly looks to me as edx (the place for third argument on 64-bit) is set to 7457, then the opaquify is inlined, but it doesn't preserve
edx and then third_arg is called with the zeroed edx.
----------------
Specs
-------------
64-bit Archlinux with arch-haskell repo
gcc -v:
```
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /build/gcc-multilib/src/gcc-5-20160209/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release
Thread model: posix
gcc version 5.3.0 (GCC)
```
ghc compile output:
```
Glasgow Haskell Compiler, Version 7.10.3, stage 2 booted by GHC version 7.10.3
Using binary package database: /usr/lib/ghc-7.10.3/package.conf.d/package.cache
wired-in package ghc-prim mapped to ghc-prim-0.4.0.0-6cdc86811872333585fa98756aa7c51e
wired-in package integer-gmp mapped to integer-gmp-1.0.0.0-3c8c40657a9870f5c33be17496806d8d
wired-in package base mapped to base-4.8.2.0-0d6d1084fbc041e1cded9228e80e264d
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.10.0.0-3c4cb52230f347282af9b2817f013181
wired-in package ghc mapped to ghc-7.10.3-3a39f8f970ff545623196002970730d1
wired-in package dph-seq not found.
wired-in package dph-par not found.
Hsc static flags:
wired-in package ghc-prim mapped to ghc-prim-0.4.0.0-6cdc86811872333585fa98756aa7c51e
wired-in package integer-gmp mapped to integer-gmp-1.0.0.0-3c8c40657a9870f5c33be17496806d8d
wired-in package base mapped to base-4.8.2.0-0d6d1084fbc041e1cded9228e80e264d
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.10.0.0-3c4cb52230f347282af9b2817f013181
wired-in package ghc mapped to ghc-7.10.3-3a39f8f970ff545623196002970730d1
wired-in package dph-seq not found.
wired-in package dph-par not found.
*** Chasing dependencies:
Chasing modules from: *Main.hs
Stable obj: []
Stable BCO: []
Ready for upsweep
[NONREC
ModSummary {
ms_hs_date = 2016-04-05 14:24:20.801997492 UTC
ms_mod = Main,
ms_textual_imps = [import (implicit) Prelude, import Data.Word]
ms_srcimps = []
}]
*** Deleting temp files:
Deleting:
compile: input file Main.hs
Created temporary directory: /tmp/ghc1541_0
*** Checking old interface for Main:
[1 of 1] Compiling Main ( Main.hs, Main.o )
*** Parser:
*** Renamer/typechecker:
*** Desugar:
Result size of Desugar (after optimization)
= {terms: 317, types: 387, coercions: 3}
*** Core Linted result of Desugar (after optimization):
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 261, types: 290, coercions: 14}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 216, types: 262, coercions: 18}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 216, types: 262, coercions: 18}
*** Core Linted result of Simplifier:
*** Specialise:
Result size of Specialise = {terms: 216, types: 262, coercions: 18}
*** Core Linted result of Specialise:
*** Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = False}):
Result size of Float out(FOS {Lam = Just 0,
Consts = True,
OverSatApps = False})
= {terms: 274, types: 305, coercions: 18}
*** Core Linted result of Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = False}):
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 407, types: 388, coercions: 70}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 463, types: 375, coercions: 25}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 430, types: 362, coercions: 25}
*** Core Linted result of Simplifier:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 426, types: 363, coercions: 25}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 426, types: 363, coercions: 25}
*** Core Linted result of Simplifier:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 310, types: 291, coercions: 25}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=2
= {terms: 248, types: 217, coercions: 25}
*** Core Linted result of Simplifier:
Result size of Simplifier iteration=3
= {terms: 336, types: 242, coercions: 25}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 336, types: 242, coercions: 25}
*** Core Linted result of Simplifier:
*** Float inwards:
Result size of Float inwards
= {terms: 336, types: 242, coercions: 25}
*** Core Linted result of Float inwards:
*** Called arity analysis:
Result size of Called arity analysis
= {terms: 336, types: 242, coercions: 25}
*** Core Linted result of Called arity analysis:
*** Simplifier:
Result size of Simplifier = {terms: 336, types: 242, coercions: 25}
*** Core Linted result of Simplifier:
*** Demand analysis:
Result size of Demand analysis
= {terms: 336, types: 242, coercions: 25}
*** Core Linted result of Demand analysis:
*** Worker Wrapper binds:
Result size of Worker Wrapper binds
= {terms: 369, types: 283, coercions: 25}
*** Core Linted result of Worker Wrapper binds:
*** Simplifier:
Result size of Simplifier iteration=1
= {terms: 354, types: 266, coercions: 25}
*** Core Linted result of Simplifier:
Result size of Simplifier = {terms: 354, types: 266, coercions: 25}
*** Core Linted result of Simplifier:
*** Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = True}):
Result size of Float out(FOS {Lam = Just 0,
Consts = True,
OverSatApps = True})
= {terms: 356, types: 267, coercions: 25}
*** Core Linted result of Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = True}):
*** Common sub-expression:
Result size of Common sub-expression
= {terms: 356, types: 267, coercions: 25}
*** Core Linted result of Common sub-expression:
*** Float inwards:
Result size of Float inwards
= {terms: 356, types: 267, coercions: 25}
*** Core Linted result of Float inwards:
*** Simplifier:
Result size of Simplifier = {terms: 356, types: 267, coercions: 25}
*** Core Linted result of Simplifier:
*** Tidy Core:
Result size of Tidy Core = {terms: 356, types: 267, coercions: 25}
*** Core Linted result of Tidy Core:
writeBinIface: 18 Names
writeBinIface: 81 dict entries
*** CorePrep:
Result size of CorePrep = {terms: 654, types: 379, coercions: 25}
*** Core Linted result of CorePrep:
*** Stg2Stg:
*** CodeGen:
*** Assembler:
/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -I. -x assembler -c /tmp/ghc1541_0/ghc_2.s -o Main.o
Upsweep completely successful.
*** Deleting temp files:
Deleting: /tmp/ghc1541_0/ghc_3.c /tmp/ghc1541_0/ghc_2.s /tmp/ghc1541_0/ghc_1.s
Warning: deleting non-existent /tmp/ghc1541_0/ghc_3.c
Warning: deleting non-existent /tmp/ghc1541_0/ghc_1.s
link: linkables are ...
LinkableM (2016-04-05 15:42:11.288210053 UTC) Main
[DotO Main.o]
Linking Main ...
*** C Compiler:
/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -c /tmp/ghc1541_0/ghc_4.c -o /tmp/ghc1541_0/ghc_5.o -I/usr/lib/ghc-7.10.3/include
*** C Compiler:
/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -c /tmp/ghc1541_0/ghc_7.s -o /tmp/ghc1541_0/ghc_8.o -I/usr/lib/ghc-7.10.3/include
*** Linker:
/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-Wl,--hash-size=31' -Wl,--reduce-memory-overheads -Wl,--no-as-needed -o Main Main.o Test.o -L/usr/lib/ghc-7.10.3/base_HQfYBxpPvuw8OunzQu6JGM -L/usr/lib/ghc-7.10.3/integ_2aU3IZNMF9a7mQ0OzsZ0dS -L/usr/lib/ghc-7.10.3/ghcpr_8TmvWUcS1U1IKHT0levwg3 -L/usr/lib/ghc-7.10.3/rts /tmp/ghc1541_0/ghc_5.o /tmp/ghc1541_0/ghc_8.o -Wl,-u,ghczmprim_GHCziTypes_Izh_static_info -Wl,-u,ghczmprim_GHCziTypes_Czh_static_info -Wl,-u,ghczmprim_GHCziTypes_Fzh_static_info -Wl,-u,ghczmprim_GHCziTypes_Dzh_static_info -Wl,-u,base_GHCziPtr_Ptr_static_info -Wl,-u,ghczmprim_GHCziTypes_Wzh_static_info -Wl,-u,base_GHCziInt_I8zh_static_info -Wl,-u,base_GHCziInt_I16zh_static_info -Wl,-u,base_GHCziInt_I32zh_static_info -Wl,-u,base_GHCziInt_I64zh_static_info -Wl,-u,base_GHCziWord_W8zh_static_info -Wl,-u,base_GHCziWord_W16zh_static_info -Wl,-u,base_GHCziWord_W32zh_static_info -Wl,-u,base_GHCziWord_W64zh_static_info -Wl,-u,base_GHCziStable_StablePtr_static_info -Wl,-u,ghczmprim_GHCziTypes_Izh_con_info -Wl,-u,ghczmprim_GHCziTypes_Czh_con_info -Wl,-u,ghczmprim_GHCziTypes_Fzh_con_info -Wl,-u,ghczmprim_GHCziTypes_Dzh_con_info -Wl,-u,base_GHCziPtr_Ptr_con_info -Wl,-u,base_GHCziPtr_FunPtr_con_info -Wl,-u,base_GHCziStable_StablePtr_con_info -Wl,-u,ghczmprim_GHCziTypes_False_closure -Wl,-u,ghczmprim_GHCziTypes_True_closure -Wl,-u,base_GHCziPack_unpackCString_closure -Wl,-u,base_GHCziIOziException_stackOverflow_closure -Wl,-u,base_GHCziIOziException_heapOverflow_closure -Wl,-u,base_ControlziExceptionziBase_nonTermination_closure -Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnMVar_closure -Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnSTM_closure -Wl,-u,base_GHCziIOziException_allocationLimitExceeded_closure -Wl,-u,base_ControlziExceptionziBase_nestedAtomically_closure -Wl,-u,base_GHCziEventziThread_blockedOnBadFD_closure -Wl,-u,base_GHCziWeak_runFinalizzerBatch_closure -Wl,-u,base_GHCziTopHandler_flushStdHandles_closure -Wl,-u,base_GHCziTopHandler_runIO_closure -Wl,-u,base_GHCziTopHandler_runNonIO_closure -Wl,-u,base_GHCziConcziIO_ensureIOManagerIsRunning_closure -Wl,-u,base_GHCziConcziIO_ioManagerCapabilitiesChanged_closure -Wl,-u,base_GHCziConcziSync_runSparks_closure -Wl,-u,base_GHCziConcziSignal_runHandlersPtr_closure -lHSbase-4.8.2.0-HQfYBxpPvuw8OunzQu6JGM -lHSinteger-gmp-1.0.0.0-2aU3IZNMF9a7mQ0OzsZ0dS -lHSghc-prim-0.4.0.0-8TmvWUcS1U1IKHT0levwg3 -lHSrts -lCffi -lgmp -lm -lrt -ldl
link: done
*** Deleting temp files:
Deleting: /tmp/ghc1541_0/ghc_10.rsp /tmp/ghc1541_0/ghc_9.rsp /tmp/ghc1541_0/ghc_8.o /tmp/ghc1541_0/ghc_7.s /tmp/ghc1541_0/ghc_6.rsp /tmp/ghc1541_0/ghc_5.o /tmp/ghc1541_0/ghc_4.c
*** Deleting temp dirs:
Deleting: /tmp/ghc1541_0
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.10.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Optimised unsafe FFI call can get wrong argument","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.10.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Attached a simple test case. It should print 7457, but the C function is called with 0 as the third argument.\r\n\r\nIf I compile with -O0 or omit the unsafe keyword in the FFI import it works as it should.\r\n\r\nIn gdb disassembly looks to me as edx (the place for third argument on 64-bit) is set to 7457, then the opaquify is inlined, but it doesn't preserve\r\nedx and then third_arg is called with the zeroed edx.\r\n\r\n----------------\r\nSpecs\r\n-------------\r\n64-bit Archlinux with arch-haskell repo\r\n\r\ngcc -v:\r\n{{{\r\nUsing built-in specs.\r\nCOLLECT_GCC=gcc\r\nCOLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/lto-wrapper\r\nTarget: x86_64-unknown-linux-gnu\r\nConfigured with: /build/gcc-multilib/src/gcc-5-20160209/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --enable-libmpx --with-system-zlib --with-isl --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --enable-gnu-indirect-function --enable-multilib --disable-werror --enable-checking=release\r\nThread model: posix\r\ngcc version 5.3.0 (GCC)\r\n}}}\r\n\r\nghc compile output:\r\n{{{\r\nGlasgow Haskell Compiler, Version 7.10.3, stage 2 booted by GHC version 7.10.3\r\nUsing binary package database: /usr/lib/ghc-7.10.3/package.conf.d/package.cache\r\nwired-in package ghc-prim mapped to ghc-prim-0.4.0.0-6cdc86811872333585fa98756aa7c51e\r\nwired-in package integer-gmp mapped to integer-gmp-1.0.0.0-3c8c40657a9870f5c33be17496806d8d\r\nwired-in package base mapped to base-4.8.2.0-0d6d1084fbc041e1cded9228e80e264d\r\nwired-in package rts mapped to builtin_rts\r\nwired-in package template-haskell mapped to template-haskell-2.10.0.0-3c4cb52230f347282af9b2817f013181\r\nwired-in package ghc mapped to ghc-7.10.3-3a39f8f970ff545623196002970730d1\r\nwired-in package dph-seq not found.\r\nwired-in package dph-par not found.\r\nHsc static flags: \r\nwired-in package ghc-prim mapped to ghc-prim-0.4.0.0-6cdc86811872333585fa98756aa7c51e\r\nwired-in package integer-gmp mapped to integer-gmp-1.0.0.0-3c8c40657a9870f5c33be17496806d8d\r\nwired-in package base mapped to base-4.8.2.0-0d6d1084fbc041e1cded9228e80e264d\r\nwired-in package rts mapped to builtin_rts\r\nwired-in package template-haskell mapped to template-haskell-2.10.0.0-3c4cb52230f347282af9b2817f013181\r\nwired-in package ghc mapped to ghc-7.10.3-3a39f8f970ff545623196002970730d1\r\nwired-in package dph-seq not found.\r\nwired-in package dph-par not found.\r\n*** Chasing dependencies:\r\nChasing modules from: *Main.hs\r\nStable obj: []\r\nStable BCO: []\r\nReady for upsweep\r\n [NONREC\r\n ModSummary {\r\n ms_hs_date = 2016-04-05 14:24:20.801997492 UTC\r\n ms_mod = Main,\r\n ms_textual_imps = [import (implicit) Prelude, import Data.Word]\r\n ms_srcimps = []\r\n }]\r\n*** Deleting temp files:\r\nDeleting: \r\ncompile: input file Main.hs\r\nCreated temporary directory: /tmp/ghc1541_0\r\n*** Checking old interface for Main:\r\n[1 of 1] Compiling Main ( Main.hs, Main.o )\r\n*** Parser:\r\n*** Renamer/typechecker:\r\n*** Desugar:\r\nResult size of Desugar (after optimization)\r\n = {terms: 317, types: 387, coercions: 3}\r\n*** Core Linted result of Desugar (after optimization):\r\n*** Simplifier:\r\nResult size of Simplifier iteration=1\r\n = {terms: 261, types: 290, coercions: 14}\r\n*** Core Linted result of Simplifier:\r\nResult size of Simplifier iteration=2\r\n = {terms: 216, types: 262, coercions: 18}\r\n*** Core Linted result of Simplifier:\r\nResult size of Simplifier = {terms: 216, types: 262, coercions: 18}\r\n*** Core Linted result of Simplifier:\r\n*** Specialise:\r\nResult size of Specialise = {terms: 216, types: 262, coercions: 18}\r\n*** Core Linted result of Specialise:\r\n*** Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = False}):\r\nResult size of Float out(FOS {Lam = Just 0,\r\n Consts = True,\r\n OverSatApps = False})\r\n = {terms: 274, types: 305, coercions: 18}\r\n*** Core Linted result of Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = False}):\r\n*** Simplifier:\r\nResult size of Simplifier iteration=1\r\n = {terms: 407, types: 388, coercions: 70}\r\n*** Core Linted result of Simplifier:\r\nResult size of Simplifier iteration=2\r\n = {terms: 463, types: 375, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\nResult size of Simplifier = {terms: 430, types: 362, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\n*** Simplifier:\r\nResult size of Simplifier iteration=1\r\n = {terms: 426, types: 363, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\nResult size of Simplifier = {terms: 426, types: 363, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\n*** Simplifier:\r\nResult size of Simplifier iteration=1\r\n = {terms: 310, types: 291, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\nResult size of Simplifier iteration=2\r\n = {terms: 248, types: 217, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\nResult size of Simplifier iteration=3\r\n = {terms: 336, types: 242, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\nResult size of Simplifier = {terms: 336, types: 242, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\n*** Float inwards:\r\nResult size of Float inwards\r\n = {terms: 336, types: 242, coercions: 25}\r\n*** Core Linted result of Float inwards:\r\n*** Called arity analysis:\r\nResult size of Called arity analysis\r\n = {terms: 336, types: 242, coercions: 25}\r\n*** Core Linted result of Called arity analysis:\r\n*** Simplifier:\r\nResult size of Simplifier = {terms: 336, types: 242, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\n*** Demand analysis:\r\nResult size of Demand analysis\r\n = {terms: 336, types: 242, coercions: 25}\r\n*** Core Linted result of Demand analysis:\r\n*** Worker Wrapper binds:\r\nResult size of Worker Wrapper binds\r\n = {terms: 369, types: 283, coercions: 25}\r\n*** Core Linted result of Worker Wrapper binds:\r\n*** Simplifier:\r\nResult size of Simplifier iteration=1\r\n = {terms: 354, types: 266, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\nResult size of Simplifier = {terms: 354, types: 266, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\n*** Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = True}):\r\nResult size of Float out(FOS {Lam = Just 0,\r\n Consts = True,\r\n OverSatApps = True})\r\n = {terms: 356, types: 267, coercions: 25}\r\n*** Core Linted result of Float out(FOS {Lam = Just 0, Consts = True, OverSatApps = True}):\r\n*** Common sub-expression:\r\nResult size of Common sub-expression\r\n = {terms: 356, types: 267, coercions: 25}\r\n*** Core Linted result of Common sub-expression:\r\n*** Float inwards:\r\nResult size of Float inwards\r\n = {terms: 356, types: 267, coercions: 25}\r\n*** Core Linted result of Float inwards:\r\n*** Simplifier:\r\nResult size of Simplifier = {terms: 356, types: 267, coercions: 25}\r\n*** Core Linted result of Simplifier:\r\n*** Tidy Core:\r\nResult size of Tidy Core = {terms: 356, types: 267, coercions: 25}\r\n*** Core Linted result of Tidy Core:\r\nwriteBinIface: 18 Names\r\nwriteBinIface: 81 dict entries\r\n*** CorePrep:\r\nResult size of CorePrep = {terms: 654, types: 379, coercions: 25}\r\n*** Core Linted result of CorePrep:\r\n*** Stg2Stg:\r\n*** CodeGen:\r\n*** Assembler:\r\n/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -I. -x assembler -c /tmp/ghc1541_0/ghc_2.s -o Main.o\r\nUpsweep completely successful.\r\n*** Deleting temp files:\r\nDeleting: /tmp/ghc1541_0/ghc_3.c /tmp/ghc1541_0/ghc_2.s /tmp/ghc1541_0/ghc_1.s\r\nWarning: deleting non-existent /tmp/ghc1541_0/ghc_3.c\r\nWarning: deleting non-existent /tmp/ghc1541_0/ghc_1.s\r\nlink: linkables are ...\r\nLinkableM (2016-04-05 15:42:11.288210053 UTC) Main\r\n [DotO Main.o]\r\nLinking Main ...\r\n*** C Compiler:\r\n/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -c /tmp/ghc1541_0/ghc_4.c -o /tmp/ghc1541_0/ghc_5.o -I/usr/lib/ghc-7.10.3/include\r\n*** C Compiler:\r\n/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -c /tmp/ghc1541_0/ghc_7.s -o /tmp/ghc1541_0/ghc_8.o -I/usr/lib/ghc-7.10.3/include\r\n*** Linker:\r\n/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-Wl,--hash-size=31' -Wl,--reduce-memory-overheads -Wl,--no-as-needed -o Main Main.o Test.o -L/usr/lib/ghc-7.10.3/base_HQfYBxpPvuw8OunzQu6JGM -L/usr/lib/ghc-7.10.3/integ_2aU3IZNMF9a7mQ0OzsZ0dS -L/usr/lib/ghc-7.10.3/ghcpr_8TmvWUcS1U1IKHT0levwg3 -L/usr/lib/ghc-7.10.3/rts /tmp/ghc1541_0/ghc_5.o /tmp/ghc1541_0/ghc_8.o -Wl,-u,ghczmprim_GHCziTypes_Izh_static_info -Wl,-u,ghczmprim_GHCziTypes_Czh_static_info -Wl,-u,ghczmprim_GHCziTypes_Fzh_static_info -Wl,-u,ghczmprim_GHCziTypes_Dzh_static_info -Wl,-u,base_GHCziPtr_Ptr_static_info -Wl,-u,ghczmprim_GHCziTypes_Wzh_static_info -Wl,-u,base_GHCziInt_I8zh_static_info -Wl,-u,base_GHCziInt_I16zh_static_info -Wl,-u,base_GHCziInt_I32zh_static_info -Wl,-u,base_GHCziInt_I64zh_static_info -Wl,-u,base_GHCziWord_W8zh_static_info -Wl,-u,base_GHCziWord_W16zh_static_info -Wl,-u,base_GHCziWord_W32zh_static_info -Wl,-u,base_GHCziWord_W64zh_static_info -Wl,-u,base_GHCziStable_StablePtr_static_info -Wl,-u,ghczmprim_GHCziTypes_Izh_con_info -Wl,-u,ghczmprim_GHCziTypes_Czh_con_info -Wl,-u,ghczmprim_GHCziTypes_Fzh_con_info -Wl,-u,ghczmprim_GHCziTypes_Dzh_con_info -Wl,-u,base_GHCziPtr_Ptr_con_info -Wl,-u,base_GHCziPtr_FunPtr_con_info -Wl,-u,base_GHCziStable_StablePtr_con_info -Wl,-u,ghczmprim_GHCziTypes_False_closure -Wl,-u,ghczmprim_GHCziTypes_True_closure -Wl,-u,base_GHCziPack_unpackCString_closure -Wl,-u,base_GHCziIOziException_stackOverflow_closure -Wl,-u,base_GHCziIOziException_heapOverflow_closure -Wl,-u,base_ControlziExceptionziBase_nonTermination_closure -Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnMVar_closure -Wl,-u,base_GHCziIOziException_blockedIndefinitelyOnSTM_closure -Wl,-u,base_GHCziIOziException_allocationLimitExceeded_closure -Wl,-u,base_ControlziExceptionziBase_nestedAtomically_closure -Wl,-u,base_GHCziEventziThread_blockedOnBadFD_closure -Wl,-u,base_GHCziWeak_runFinalizzerBatch_closure -Wl,-u,base_GHCziTopHandler_flushStdHandles_closure -Wl,-u,base_GHCziTopHandler_runIO_closure -Wl,-u,base_GHCziTopHandler_runNonIO_closure -Wl,-u,base_GHCziConcziIO_ensureIOManagerIsRunning_closure -Wl,-u,base_GHCziConcziIO_ioManagerCapabilitiesChanged_closure -Wl,-u,base_GHCziConcziSync_runSparks_closure -Wl,-u,base_GHCziConcziSignal_runHandlersPtr_closure -lHSbase-4.8.2.0-HQfYBxpPvuw8OunzQu6JGM -lHSinteger-gmp-1.0.0.0-2aU3IZNMF9a7mQ0OzsZ0dS -lHSghc-prim-0.4.0.0-8TmvWUcS1U1IKHT0levwg3 -lHSrts -lCffi -lgmp -lm -lrt -ldl\r\nlink: done\r\n*** Deleting temp files:\r\nDeleting: /tmp/ghc1541_0/ghc_10.rsp /tmp/ghc1541_0/ghc_9.rsp /tmp/ghc1541_0/ghc_8.o /tmp/ghc1541_0/ghc_7.s /tmp/ghc1541_0/ghc_6.rsp /tmp/ghc1541_0/ghc_5.o /tmp/ghc1541_0/ghc_4.c\r\n*** Deleting temp dirs:\r\nDeleting: /tmp/ghc1541_0\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->8.0.2https://gitlab.haskell.org/ghc/ghc/-/issues/11683compiled files don't load in ghci2019-07-07T18:29:06Zgeorge.colpittscompiled files don't load in ghcicompiled files don't load in ghci
```
ghc -DYNAMIC bug.hs
[1 of 1] Compiling Main ( bug.hs, bug.o )
Linking bug ...
bash-3.2$ ghci -ignore-dot-ghci
GHCi, version 8.0.0.20160204: http://www.haskell.org/ghc/ :? for help
Prel...compiled files don't load in ghci
```
ghc -DYNAMIC bug.hs
[1 of 1] Compiling Main ( bug.hs, bug.o )
Linking bug ...
bash-3.2$ ghci -ignore-dot-ghci
GHCi, version 8.0.0.20160204: http://www.haskell.org/ghc/ :? for help
Prelude> Prelude> :load bug
[1 of 1] Compiling Main ( bug.hs, interpreted )
Ok, modules loaded: Main.
*Main> :show modules
Main ( bug.hs, interpreted )
*Main>
```
According to the doc, file:///usr/local/share/doc/ghc-8.0.0.20160204/html/users_guide/ghci.html\#loading-compiled-code, this should work:
```
Note the -dynamic flag to GHC: GHCi uses dynamically-linked object code (if you are on a platform that supports it), and so in order to use compiled code with GHCi it must be compiled for dynamic linking.
```
Similarly #8736\##11683 says the same thing:
```
if you say :load Foo in GHCi
Foo was compiled with -dynamic: loads Foo.o
```
Interestingly -fobject-code does work:
```
ghci -ignore-dot-ghci -fobject-code
GHCi, version 8.0.0.20160204: http://www.haskell.org/ghc/ :? for help
Prelude> :load bug
[1 of 1] Compiling Main ( bug.hs, bug.o )
Ok, modules loaded: Main.
Prelude Main>
```
Unfortunately when I add -v I don't see why it works.
```
ghci -v -ignore-dot-ghci -fobject-code
```
It doesn't seem to use just ghc to compile , it also uses gcc, see attached file.
```
ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.0.0.20160204
bash-3.2$ ghc --info
[("Project name","The Glorious Glasgow Haskell Compilation System")
,("GCC extra via C opts"," -fwrapv -fno-builtin")
,("C compiler command","/usr/bin/gcc")
,("C compiler flags"," -m64 -fno-stack-protector")
,("C compiler link flags"," -m64")
,("Haskell CPP command","/usr/bin/gcc")
,("Haskell CPP flags","-E -undef -traditional -Wno-invalid-pp-token -Wno-unicode -Wno-trigraphs")
,("ld command","/usr/bin/ld")
,("ld flags"," -arch x86_64")
,("ld supports compact unwind","YES")
,("ld supports build-id","NO")
,("ld supports filelist","YES")
,("ld is GNU ld","NO")
,("ar command","/usr/bin/ar")
,("ar flags","clqs")
,("ar supports at file","NO")
,("touch command","touch")
,("dllwrap command","/bin/false")
,("windres command","/bin/false")
,("libtool command","libtool")
,("perl command","/usr/bin/perl")
,("cross compiling","NO")
,("target os","OSDarwin")
,("target arch","ArchX86_64")
,("target word size","8")
,("target has GNU nonexec stack","False")
,("target has .ident directive","True")
,("target has subsections via symbols","True")
,("Unregisterised","NO")
,("LLVM llc command","/usr/local/bin/llc-3.7")
,("LLVM opt command","/usr/local/bin/opt-3.7")
,("Project version","8.0.0.20160204")
,("Project Git commit id","e2230228906a1c0fa1f86a0c1aa18d87de3cc49d")
,("Booter version","7.10.2")
,("Stage","2")
,("Build platform","x86_64-apple-darwin")
,("Host platform","x86_64-apple-darwin")
,("Target platform","x86_64-apple-darwin")
,("Have interpreter","YES")
,("Object splitting supported","YES")
,("Have native code generator","YES")
,("Support SMP","YES")
,("Tables next to code","YES")
,("RTS ways","l debug thr thr_debug thr_l thr_p dyn debug_dyn thr_dyn thr_debug_dyn l_dyn thr_l_dyn")
,("RTS expects libdw","NO")
,("Support dynamic-too","YES")
,("Support parallel --make","YES")
,("Support reexported-modules","YES")
,("Support thinning and renaming package flags","YES")
,("Requires unified installed package IDs","YES")
,("Uses package keys","YES")
,("Uses unit IDs","YES")
,("Dynamic by default","NO")
,("GHC Dynamic","YES")
,("GHC Profiled","NO")
,("Leading underscore","YES")
,("Debug on","False")
,("LibDir","/usr/local/lib/ghc-8.0.0.20160204")
,("Global Package DB","/usr/local/lib/ghc-8.0.0.20160204/package.conf.d")
]
```https://gitlab.haskell.org/ghc/ghc/-/issues/11358GHC generics has differing conFixity behavior between 7.10.3 and 8.12019-07-07T18:30:45ZRyan ScottGHC generics has differing conFixity behavior between 7.10.3 and 8.1Compile the following program with GHC 7.10.3 and 8.1:
```hs
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
module Main (main) where
import GHC.Gen...Compile the following program with GHC 7.10.3 and 8.1:
```hs
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
module Main (main) where
import GHC.Generics
infixr 1 `T`
data T a = T a a deriving Generic
instance HasFixity (T a)
data I a = a `I` a deriving Generic
instance HasFixity (I a)
class HasFixity a where
fixity :: a -> Fixity
default fixity :: (Generic a, GHasFixity (Rep a)) => a -> Fixity
fixity = gfixity . from
class GHasFixity f where
gfixity :: f a -> Fixity
instance GHasFixity f => GHasFixity (D1 d f) where
gfixity (M1 x) = gfixity x
instance Constructor c => GHasFixity (C1 c f) where
gfixity c = conFixity c
main :: IO ()
main = do
putStrLn $ show (fixity (T "a" "b")) ++ ", " ++ show (fixity ("a" `I` "b"))
```
On GHC 7.10.3, it yields `Prefix, Infix LeftAssociative 9`, but on GHC 8.1, it yields `Infix RightAssociative 1, Prefix`. Why? The implementation of `deriving Generic(1)` changed slightly in GHC 8.1. Before, it would only assign a fixity of `Infix` if a constructor was *declared* infix. But GHC 8.1 no longer checks for this—it first checks if there is a user-supplied fixity declaration, and if so, uses that as the `Fixity`. Otherwise, it defaults to `Prefix`, even if the datatype was declared infix!
The design of `Fixity` perhaps leaves something to be desired, but at the very least, we should ensure nothing `Fixity`-related breaks for now.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------ |
| Version | 8.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler (CodeGen) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | kosmikus |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GHC generics has differing conFixity behavior between 7.10.3 and 8.1","status":"New","operating_system":"","component":"Compiler (CodeGen)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"RyanGlScott"},"version":"8.1","keywords":["Generics"],"differentials":[],"test_case":"","architecture":"","cc":["kosmikus"],"type":"Bug","description":"Compile the following program with GHC 7.10.3 and 8.1:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE DefaultSignatures #-}\r\n{-# LANGUAGE DeriveGeneric #-}\r\n{-# LANGUAGE FlexibleContexts #-}\r\n{-# LANGUAGE FlexibleInstances #-}\r\nmodule Main (main) where\r\n\r\nimport GHC.Generics\r\n\r\ninfixr 1 `T`\r\ndata T a = T a a deriving Generic\r\ninstance HasFixity (T a)\r\n\r\ndata I a = a `I` a deriving Generic\r\ninstance HasFixity (I a)\r\n\r\nclass HasFixity a where\r\n fixity :: a -> Fixity\r\n default fixity :: (Generic a, GHasFixity (Rep a)) => a -> Fixity\r\n fixity = gfixity . from\r\n\r\nclass GHasFixity f where\r\n gfixity :: f a -> Fixity\r\n\r\ninstance GHasFixity f => GHasFixity (D1 d f) where\r\n gfixity (M1 x) = gfixity x\r\n\r\ninstance Constructor c => GHasFixity (C1 c f) where\r\n gfixity c = conFixity c\r\n\r\nmain :: IO ()\r\nmain = do\r\n putStrLn $ show (fixity (T \"a\" \"b\")) ++ \", \" ++ show (fixity (\"a\" `I` \"b\"))\r\n}}}\r\n\r\nOn GHC 7.10.3, it yields `Prefix, Infix LeftAssociative 9`, but on GHC 8.1, it yields `Infix RightAssociative 1, Prefix`. Why? The implementation of `deriving Generic(1)` changed slightly in GHC 8.1. Before, it would only assign a fixity of `Infix` if a constructor was ''declared'' infix. But GHC 8.1 no longer checks for this—it first checks if there is a user-supplied fixity declaration, and if so, uses that as the `Fixity`. Otherwise, it defaults to `Prefix`, even if the datatype was declared infix!\r\n\r\nThe design of `Fixity` perhaps leaves something to be desired, but at the very least, we should ensure nothing `Fixity`-related breaks for now.","type_of_failure":"OtherFailure","blocking":[]} -->8.0.1Ryan ScottRyan Scotthttps://gitlab.haskell.org/ghc/ghc/-/issues/11126Entered absent arg in a Repa program2021-04-29T21:20:00ZtuplanollaEntered absent arg in a Repa programConsider the following program.
```hs
module Main where
import Data.Array.Repa
data Stuff = !(Array U DIM1 Double) `With` !Double deriving Show
through :: Maybe Double -> Stuff -> Stuff
m `through` (a `With` _) =
let b = a +^ (nega...Consider the following program.
```hs
module Main where
import Data.Array.Repa
data Stuff = !(Array U DIM1 Double) `With` !Double deriving Show
through :: Maybe Double -> Stuff -> Stuff
m `through` (a `With` _) =
let b = a +^ (negate `smap` sumS (extend (Z :. All :. (1 :: Int)) a))
c = maybe b (const (negate `smap` a)) m in
computeUnboxedS c `With` sumAllS b
main :: IO ()
main = print $ Just 1 `through` (fromListUnboxed (Z :. 1) [1] `With` 1)
```
It should produce the following result once run.
```hs
AUnboxed (Z :. 1) (fromList [-1.0]) `With` 0.0
```
However, when built using `repa-3.4.0.1` and compiled with the options
`-O3 -Wall -funfolding-keeness-factor1000 -funfolding-use-threshold1000`,
it crashes as follows.
```hs
Main: Oops! Entered absent arg arr2 Array D DIM1 Double
```
Adding `-fno-strictness` to the compiler options or
removing strictness annotations from the code makes the problem disappear, so
this looks like a strictness analyzer problem.
The libraries used were
- `QuickCheck-2.8.1`,
- `array-0.5.1.0`,
- `base-4.8.1.0`,
- `bytestring-0.10.6.0`,
- `containers-0.5.6.2`,
- `deepseq-1.4.1.1`,
- `ghc-prim-0.4.0.0`,
- `integer-gmp-1.0.0.0`,
- `pretty-1.1.2.0`,
- `primitive-0.6`,
- `random-1.1`,
- `repa-3.4.0.1`,
- `template-haskell-2.10.0.0`,
- `tf-random-0.5`,
- `time-1.5.0.1`,
- `transformers-0.4.2.0` and
- `vector-0.10.12.3`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.10.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Entered absent arg in a Repa program","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.10.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider the following program.\r\n\r\n{{{#!hs\r\nmodule Main where\r\n\r\nimport Data.Array.Repa\r\n\r\ndata Stuff = !(Array U DIM1 Double) `With` !Double deriving Show\r\n\r\nthrough :: Maybe Double -> Stuff -> Stuff\r\nm `through` (a `With` _) =\r\n let b = a +^ (negate `smap` sumS (extend (Z :. All :. (1 :: Int)) a))\r\n c = maybe b (const (negate `smap` a)) m in\r\n computeUnboxedS c `With` sumAllS b\r\n\r\nmain :: IO ()\r\nmain = print $ Just 1 `through` (fromListUnboxed (Z :. 1) [1] `With` 1)\r\n}}}\r\n\r\nIt should produce the following result once run.\r\n\r\n{{{#!hs\r\nAUnboxed (Z :. 1) (fromList [-1.0]) `With` 0.0\r\n}}}\r\n\r\nHowever, when built using `repa-3.4.0.1` and compiled with the options\r\n`-O3 -Wall -funfolding-keeness-factor1000 -funfolding-use-threshold1000`,\r\nit crashes as follows.\r\n\r\n{{{#!hs\r\nMain: Oops! Entered absent arg arr2 Array D DIM1 Double\r\n}}}\r\n\r\nAdding `-fno-strictness` to the compiler options or\r\nremoving strictness annotations from the code makes the problem disappear, so\r\nthis looks like a strictness analyzer problem.\r\n\r\nThe libraries used were\r\n\r\n* `QuickCheck-2.8.1`,\r\n* `array-0.5.1.0`,\r\n* `base-4.8.1.0`,\r\n* `bytestring-0.10.6.0`,\r\n* `containers-0.5.6.2`,\r\n* `deepseq-1.4.1.1`,\r\n* `ghc-prim-0.4.0.0`,\r\n* `integer-gmp-1.0.0.0`,\r\n* `pretty-1.1.2.0`,\r\n* `primitive-0.6`,\r\n* `random-1.1`,\r\n* `repa-3.4.0.1`,\r\n* `template-haskell-2.10.0.0`,\r\n* `tf-random-0.5`,\r\n* `time-1.5.0.1`,\r\n* `transformers-0.4.2.0` and\r\n* `vector-0.10.12.3`.","type_of_failure":"OtherFailure","blocking":[]} -->9.0.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/11051GHCi with +t option set shows type representations2019-07-07T18:32:24ZBen GamariGHCi with +t option set shows type representationshvr reported this morning that defining a data type in GHCi with the show types (`:set +t`) option set results in additional unexpected output. For instance,
```
$ inplace/bin/ghc-stage2 --interactive
GHCi, version 7.11.20151101: http:/...hvr reported this morning that defining a data type in GHCi with the show types (`:set +t`) option set results in additional unexpected output. For instance,
```
$ inplace/bin/ghc-stage2 --interactive
GHCi, version 7.11.20151101: http://www.haskell.org/ghc/ :? for help
Prelude> :set +t
Prelude> data Hi
$tcHi :: TyCon
$trModule :: Module
data Hi
Prelude>
```
The `$tcHi` and `$trModule` bindings are details of the Typeable implementation introduced in [D1404](https://phabricator.haskell.org/D1404) and should likely be hidden from the user.
This would be trivial to fix in `InteractiveUI.printTypeOfNames` except for the fact that we currently have no way to identify this sort of `Name`. In fact any knowledge that the name was generated appears to have been thrown away as early as `OccName.mkTyConRepSysOcc`.8.0.1Ben GamariBen Gamarihttps://gitlab.haskell.org/ghc/ghc/-/issues/11041EventLog write fails if entire buffer is not written2019-07-07T18:32:27ZsseveranceEventLog write fails if entire buffer is not writtenRecently I was trying to use ThreadScope to run down a performance issue. I ran into what I believe is a corner case with flushing the eventlog data to disk. The program was generating hundreds of millions of events every few minutes.
T...Recently I was trying to use ThreadScope to run down a performance issue. I ran into what I believe is a corner case with flushing the eventlog data to disk. The program was generating hundreds of millions of events every few minutes.
The function `printAndClearEventBuf` uses `fwrite` to flush the buffer to disk. What I observed is that with larger buffers it would only succeed in writing the first 4096 bytes. After it would print out its `debugBelch` message a number of times the program would crash. It does not crash if not run with the eventlog `-l` flag.
My understanding is that `fwrite` might need to be called in a loop to ensure that all data is written. `fwrite` is not guaranteed to always write the entire requested buffer.
I don't have a good test case for this, but if there is agreement about potential issues with flushing the buffer I am more than happy to provide a patch.8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/10236DWARF unwind info is broken2019-07-07T18:36:57ZthoughtpoliceDWARF unwind info is brokenAs reported by `bitonic` and `petermw` on `#ghc` (April 2nd):
```
07:02 < bitonic> I'm trying to get a meaningful backtrace with DWARF, using
<https://ghc.haskell.org/trac/ghc/wiki/DWARF> as a guide. however, all I ge...As reported by `bitonic` and `petermw` on `#ghc` (April 2nd):
```
07:02 < bitonic> I'm trying to get a meaningful backtrace with DWARF, using
<https://ghc.haskell.org/trac/ghc/wiki/DWARF> as a guide. however, all I get is
`Backtrace stopped: previous frame identical to this frame (corrupt stack?)`
07:03 < bitonic> I've re-built GHC 7.10.1 using `GhcRtsHcOpts += -g` and `GhcLibHcOpts += -g`, even if
I'm not sure it's even necessary
07:04 < bitonic> are there any additional steps I should take? or any way to make sure that the binary
I'm generating is sane?
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------------- |
| Version | 7.10.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler (Debugging) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | scpmw |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"DWARF unwind info is broken","status":"New","operating_system":"","component":"Compiler (Debugging)","related":[],"milestone":"7.10.2","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.10.1","keywords":["dwarf"],"differentials":[],"test_case":"","architecture":"","cc":["scpmw"],"type":"Bug","description":"As reported by `bitonic` and `petermw` on `#ghc` (April 2nd):\r\n\r\n{{{\r\n07:02 < bitonic> I'm trying to get a meaningful backtrace with DWARF, using \r\n <https://ghc.haskell.org/trac/ghc/wiki/DWARF> as a guide. however, all I get is \r\n `Backtrace stopped: previous frame identical to this frame (corrupt stack?)`\r\n07:03 < bitonic> I've re-built GHC 7.10.1 using `GhcRtsHcOpts += -g` and `GhcLibHcOpts += -g`, even if \r\n I'm not sure it's even necessary\r\n07:04 < bitonic> are there any additional steps I should take? or any way to make sure that the binary \r\n I'm generating is sane?\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->7.10.2