GHC: Ticket Query
http://ghc.haskell.org/trac/ghc/query?status=!closed&reporter=rwbarton&order=priority
The Glasgow Haskell Compileren-USGHChttp://ghc.haskell.org/trac/ghc/chrome/site/ghc_logo.png
http://ghc.haskell.org/trac/ghc/query?status=!closed&reporter=rwbarton&order=priority
Trac 1.0.1
http://ghc.haskell.org/trac/ghc/ticket/9929
http://ghc.haskell.org/trac/ghc/ticket/9929#9929: New alias handling not compatible with LLVM 3.4Fri, 26 Dec 2014 19:12:32 GMTrwbarton<p>
As reported by Joachim here: <a class="ext-link" href="https://www.haskell.org/pipermail/ghc-devs/2014-November/007480.html"><span class="icon"></span>https://www.haskell.org/pipermail/ghc-devs/2014-November/007480.html</a>, and it happens for me too. It seems to affect every program compiled with <tt>-fllvm</tt>; T5681 just happens to be the only such program in the normal test suite.
</p>
<p>
Faced with the definitions
</p>
<pre class="wiki">@Main_zdwwork_info_itable$def = internal constant %Main_zdwwork_entry_struct<{
i64 add (i64 sub (i64 ptrtoint (i8* @S2ZH_srt to i64),i64 ptrtoint (
void (i64*, i64*, i64*, i64, i64, i64, i64, i64, i64, i64)*
@Main_zdwwork_info$def to i64)),i64 8),
i64 4294967299, i64 0, i64 4294967311}>,
section "X98A__STRIP,__me3", align 8
@Main_zdwwork_info_itable = alias i8* bitcast
(%Main_zdwwork_entry_struct* @Main_zdwwork_info_itable$def to i8*)
</pre><p>
LLVM 3.4 produced the assembly
</p>
<pre class="wiki"> .type Main_zdwwork_info_itable,@object # @Main_zdwwork_info_itable
.section .rodata,"a",@progbits ; note .rodata, not X98A__STRIP,__me3!
.globl Main_zdwwork_info_itable
.align 16
Main_zdwwork_info_itable:
.quad (S2ZH_srt$def-Main_zdwwork_info$def)+8
.quad 4294967299 # 0x100000003
.quad 0 # 0x0
.quad 4294967311 # 0x10000000f
.size Main_zdwwork_info_itable, 32
</pre><p>
At first I thought this was an LLVM bug, but after reading <a class="ext-link" href="http://llvm.org/docs/LangRef.html#linkage-types"><span class="icon"></span>http://llvm.org/docs/LangRef.html#linkage-types</a> I'm not sure; maybe the <tt>internal</tt> linkage type means that <tt>@Main_zdwwork_info_itable$def</tt> is just a constant value without any "identity", so the LLVM optimizer is free to drop it, merge it with another constant, or move it to another section?
</p>
<p>
One workaround would be to use external linkage for these <tt>foo_info_itable$def</tt> symbols, and then if desired (to reduce symbol table size), strip out any <tt>.global bar$def</tt> statements in the LLVM mangler...?
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9929#changelog
http://ghc.haskell.org/trac/ghc/ticket/3575
http://ghc.haskell.org/trac/ghc/ticket/3575#3575: mkStdGen and split conspire to make some programs predictableMon, 12 Oct 2009 04:45:04 GMTrwbarton<p>
The following program <tt>random.hs</tt> is intended to produce a line containing 30 random 0s or 1s. It is not an example of the best way to use System.Random, but it looks innocuous enough.
</p>
<pre class="wiki">import Control.Monad
import System.Random
print0or1 = do
g <- newStdGen
putStr . show . fst $ randomR (0, 1 :: Int) g
main = replicateM_ 30 print0or1 >> putStrLn ""
</pre><p>
Let's try running it a thousand times:
</p>
<pre class="wiki">rwbarton@functor:/tmp$ ghc-6.10.1 -O2 --make random
[1 of 1] Compiling Main ( random.hs, random.o )
Linking random ...
rwbarton@functor:/tmp$ for i in `seq 1 1000` ; do ./random >> random.out ; done
rwbarton@functor:/tmp$ sort random.out | uniq | wc -l
60
</pre><p>
That's odd... there are 2<sup>30</sup> possible output lines, but when I tried to generate 1000 random ones, I only got 60 distinct outputs. Why did that happen?
</p>
<p>
One might think this is due to poor initial seeding of the random number generator (due to the time not changing very much during the test), but this is not the case. Attached is a fancier version of the program which reads an initial seed from <tt>/dev/urandom</tt>; it exhibits the same behavior.
</p>
<p>
This phenomenon is not too hard to explain. It is ultimately due to a poor interaction between <tt>mkStdGen</tt> and <tt>split</tt>. First, we need to know a bit about the design of System.Random (some statements simplified slightly for this discussion).
</p>
<ul><li>The state of the RNG consists of two <tt>Int32</tt>s, <tt>s1</tt> and <tt>s2</tt>.
</li></ul><ul><li>The initial state produced by mkStdGen almost always has <tt>s2</tt> equal to 1. (Extremely rarely, it might have <tt>s2</tt> equal to 2. We'll ignore this as it doesn't affect the argument.)
</li></ul><ul><li>To generate a random 0 or 1, we first generate a new state using some simple functions <tt>s1' = next1(s1)</tt>, <tt>s2' = next2(s2)</tt>. (Note that <tt>s1</tt> and <tt>s2</tt> "evolve" independently.) The random value returned is the lowest bit of <tt>s1'</tt> minus <tt>s2'</tt>.
</li></ul><ul><li>Splitting the generator <tt>(s1, s2)</tt> yields the two generators <tt>(s1+1, next2(s2))</tt> and <tt>(next1(s1), s2-1)</tt>.
</li></ul><p>
Our program functions as follows.
</p>
<ul><li>Initialize the generator stored in <tt>theStdGen</tt> (<tt>s1</tt> is some varying value <tt>a</tt>, <tt>s2</tt> is 1).
</li></ul><ul><li>Repeatedly split the generator, replacing it with the first output, and use the second output to generate a 0 or 1.
</li></ul><p>
If we watch <tt>theStdGen</tt> while our program runs, we will see that <tt>s1</tt> is incremented by 1 at each step, while <tt>s2</tt> follows the fixed sequence <tt>1</tt>, <tt>next2(1)</tt>, <tt>next2(next2(1))</tt>, etc. The 0 or 1 we output at the <tt>k</tt>th step is thus the lowest bit of <tt>next1(next1(a+k-1))</tt> minus <tt>b</tt><sub>k</sub>, where <tt>b</tt><sub>k</sub> is some fixed sequence. And as <tt>k</tt> varies, <tt>next1(next1(a+k-1))</tt> turns out to be just an arithmetic sequence with fixed difference modulo a fixed prime so its lowest bits are extremely predictable even without knowing <tt>a</tt>.
</p>
<p>
This issue can be fixed to some extent, without breaking backwards compatibility, by adding another method (besides <tt>mkStdGen</tt>) to create a generator, which does not have predictable <tt>s2</tt>, and using it to initialize the system RNG.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/3575#changelog
http://ghc.haskell.org/trac/ghc/ticket/8253
http://ghc.haskell.org/trac/ghc/ticket/8253#8253: example "Core syntax" is ancientSun, 08 Sep 2013 01:20:30 GMTrwbarton<p>
<a href="http://www.haskell.org/ghc/docs/7.6.3/html/users_guide/options-debugging.html#idp39365504">User's guide section 4.19.5</a> has some funky "Core syntax" that (according to git blame) dates back to at least 2000, and probably longer ago than that. It could use an update.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8253#changelog
http://ghc.haskell.org/trac/ghc/ticket/8300
http://ghc.haskell.org/trac/ghc/ticket/8300#8300: split-objs doesn't split on LLVMSat, 14 Sep 2013 22:35:28 GMTrwbarton<p>
<tt>-split-objs</tt> is allowed with <tt>-fllvm</tt>, but it doesn't really do anything. E.g. in my perf-llvm build I have a <tt>libHSbase-4.7.0.0.a</tt> with <tt>Applicative__1.o</tt>, <tt>Arrow__1.o</tt> etc.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8300#changelog
http://ghc.haskell.org/trac/ghc/ticket/8311
http://ghc.haskell.org/trac/ghc/ticket/8311#8311: suboptimal code generated for even :: Int -> Bool by NCG (x86, x86_64)Mon, 16 Sep 2013 21:37:19 GMTrwbarton<p>
This appears to be the x86 assembly for a specialization for <tt>even :: Int -> Bool</tt> that's produced by a SPECIALISE pragma for <tt>(^) :: Int -> Int -> Int</tt> in GHC.Real. The relevant bit is offsets <tt>0x2c</tt> through <tt>0x3b</tt>.
</p>
<pre class="wiki">
0000000c <base_GHCziReal_evenzuzdseven1_info>:
c: 8b 45 00 mov 0x0(%ebp),%eax
f: c7 45 00 2c 00 00 00 movl $0x2c,0x0(%ebp)
12: R_386_32 .text
16: 89 c6 mov %eax,%esi
18: f7 c6 03 00 00 00 test $0x3,%esi
1e: 75 0c jne 2c <c8gO_info>
20: ff 26 jmp *(%esi)
22: 66 90 xchg %ax,%ax
24: 00 00 add %al,(%eax)
26: 00 00 add %al,(%eax)
28: 20 00 and %al,(%eax)
...
0000002c <c8gO_info>:
2c: b8 02 00 00 00 mov $0x2,%eax
31: 89 c1 mov %eax,%ecx
33: 8b 46 03 mov 0x3(%esi),%eax
36: 99 cltd
37: f7 f9 idiv %ecx
39: 85 d2 test %edx,%edx
3b: 75 0b jne 48 <c8gO_info+0x1c>
3d: be 02 00 00 00 mov $0x2,%esi
3e: R_386_32 ghczmprim_GHCziTypes_True_closure
42: 83 c5 04 add $0x4,%ebp
45: ff 65 00 jmp *0x0(%ebp)
48: be 01 00 00 00 mov $0x1,%esi
49: R_386_32 ghczmprim_GHCziTypes_False_closure
4d: 83 c5 04 add $0x4,%ebp
50: ff 65 00 jmp *0x0(%ebp)
</pre><p>
It would be much better to do a simple <tt>testb $0x1,0x3(%esi)</tt> in place of the first six instructions of <tt>c8gO_info</tt>.
</p>
<p>
The NCG generates similar code on x86_64.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8311#changelog
http://ghc.haskell.org/trac/ghc/ticket/8321
http://ghc.haskell.org/trac/ghc/ticket/8321#8321: improve basic block layout on LLVM backend by predicting stack/heap checksTue, 17 Sep 2013 18:53:36 GMTrwbarton<p>
Currently we don't give the LLVM optimizer any information about which branch of an <tt>if</tt> is likely to be taken. As a result, the optimizer is likely to produce a basic block layout which is not optimal. Improving the layout can improve performance through better instruction cache usage and better branch prediction by the hardware.
</p>
<p>
We can control LLVM's idea of what is likely with the <tt>llvm.expect</tt> intrinsic function. Some obvious branches which we can predict accurately are the stack and heap checks that appear near the entry of many functions.
</p>
<p>
Here's a small example of some Cmm code and the output of the LLVM optimizer/compiler.
</p>
<pre class="wiki"> block_c2Lc_entry() // [R1, R2]
{ info_tbl: [(c2Lc,
label: block_c2Lc_info
rep:StackRep [])]
stack_info: arg_space: 0 updfr_space: Nothing
}
{offset
c2Lc:
Hp = Hp + 24;
if (Hp > HpLim) goto c2Lm; else goto c2Ll;
c2Lm:
HpAlloc = 24;
R2 = R2;
R1 = R1;
call stg_gc_pp(R2, R1) args: 8, res: 8, upd: 24;
c2Ll:
I64[Hp - 16] = :_con_info;
P64[Hp - 8] = R1;
P64[Hp] = R2;
R1 = Hp - 14;
Sp = Sp + 8;
call (P64[Sp])(R1) args: 24, res: 0, upd: 24;
}
}]
</pre><pre class="wiki">
00000000000002b8 <c2Lc_info>:
2b8: 4c 89 e0 mov %r12,%rax
2bb: 4c 8d 60 18 lea 0x18(%rax),%r12
2bf: 4d 3b a5 18 01 00 00 cmp 0x118(%r13),%r12
2c6: 76 10 jbe 2d8 <c2Lc_info+0x20>
2c8: 49 c7 85 48 01 00 00 movq $0x18,0x148(%r13)
2cf: 18 00 00 00
2d3: e9 00 00 00 00 jmpq 2d8 <c2Lc_info+0x20>
2d4: R_X86_64_PC32 stg_gc_pp+0xfffffffffffffffc
2d8: 48 c7 40 08 00 00 00 movq $0x0,0x8(%rax)
2df: 00
2dc: R_X86_64_32S ghczmprim_GHCziTypes_ZC_con_info
2e0: 48 89 58 10 mov %rbx,0x10(%rax)
2e4: 4c 89 70 18 mov %r14,0x18(%rax)
2e8: 48 8b 45 08 mov 0x8(%rbp),%rax
2ec: 48 83 c5 08 add $0x8,%rbp
2f0: 49 8d 5c 24 f2 lea -0xe(%r12),%rbx
2f5: ff e0 jmpq *%rax
2f7: 90 nop
</pre><p>
It would likely be better to invert the branch at <tt>2c6</tt> to a <tt>ja</tt>, so that the common case is adjacent to the function entry, and when <tt>llvm.expect</tt> is used on the condition in the branch, the LLVM optimizer does produce this alternate layout.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8321#changelog
http://ghc.haskell.org/trac/ghc/ticket/8372
http://ghc.haskell.org/trac/ghc/ticket/8372#8372: enable -dcmm-lint by default for .cmm input filesFri, 27 Sep 2013 22:14:36 GMTrwbarton<p>
I'm finding it's quite easy to write <tt>.cmm</tt> files with subtle errors that cause ghc to emit code that wasn't what I wanted! For example, I wrote a comparison between two arguments of different integer sizes and the code generator picked the wrong size. After tracking down the bug, I tried <tt>-dcmm-lint</tt> and it caught my error right away.
</p>
<p>
It makes sense not to have <tt>-dcmm-lint</tt> enabled by default for Cmm produced from Stg, but I've seen here on the GHC wiki that <tt>-dcmm-lint</tt> is advised for hand-written <tt>.cmm</tt> files. But <tt>integer-gmp</tt>, and probably many other packages, don't build <tt>.cmm</tt> files with <tt>-dcmm-lint</tt>. Is there a reason we can't/shouldn't just make it the default?
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8372#changelog
http://ghc.haskell.org/trac/ghc/ticket/8859
http://ghc.haskell.org/trac/ghc/ticket/8859#8859: import conditionalization in System.Posix.Files.Common is wrongSat, 08 Mar 2014 01:54:07 GMTrwbarton<p>
<tt>System/Posix/Files/Common.hsc</tt> imports <tt>Data.Int</tt> and <tt>Data.Ratio</tt> conditionally, to avoid "unused import" compiler warnings:
</p>
<pre class="wiki">#if defined(HAVE_STRUCT_STAT_ST_CTIM) || \
defined(HAVE_STRUCT_STAT_ST_MTIM) || \
defined(HAVE_STRUCT_STAT_ST_ATIM) || \
defined(HAVE_STRUCT_STAT_ST_ATIMESPEC) || \
defined(HAVE_STRUCT_STAT_ST_MTIMESPEC) || \
defined(HAVE_STRUCT_STAT_ST_CTIMESPEC)
import Data.Int
import Data.Ratio
#endif
</pre><p>
but those modules are actually used in functions like
</p>
<pre class="wiki">accessTimeHiRes (FileStatus stat) =
unsafePerformIO $ withForeignPtr stat $ \stat_ptr -> do
sec <- (#peek struct stat, st_atime) stat_ptr :: IO EpochTime
#ifdef HAVE_STRUCT_STAT_ST_ATIM
nsec <- (#peek struct stat, st_atim.tv_nsec) stat_ptr :: IO (#type long)
let frac = toInteger nsec % 10^(9::Int)
#elif HAVE_STRUCT_STAT_ST_ATIMESPEC
nsec <- (#peek struct stat, st_atimespec.tv_nsec) stat_ptr :: IO (#type long)
let frac = toInteger nsec % 10^(9::Int)
#elif HAVE_STRUCT_STAT_ST_ATIMENSEC
nsec <- (#peek struct stat, st_atimensec) stat_ptr :: IO (#type long)
let frac = toInteger nsec % 10^(9::Int)
#elif HAVE_STRUCT_STAT_ST_ATIME_N
nsec <- (#peek struct stat, st_atime_n) stat_ptr :: IO (#type int)
let frac = toInteger nsec % 10^(9::Int)
#elif HAVE_STRUCT_STAT_ST_UATIME
usec <- (#peek struct stat, st_uatime) stat_ptr :: IO (#type int)
let frac = toInteger usec % 10^(6::Int)
#else
let frac = 0
#endif
return $ fromRational $ toRational sec + frac
</pre><p>
so there should be additional tests for <tt>defined(HAVE_STRUCT_STAT_ST_ATIMENSEC)</tt>, <tt>defined(HAVE_STRUCT_STAT_ST_ATIME_N)</tt>, ... (15 total).
</p>
<p>
Or, maybe there's a better alternative, since this is very long-winded and fragile...
</p>
<p>
This breaks the build on Android, which has <tt>st_atimensec</tt>.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8859#changelog
http://ghc.haskell.org/trac/ghc/ticket/9210
http://ghc.haskell.org/trac/ghc/ticket/9210#9210: "overlapping instances" through FunctionalDependenciesMon, 16 Jun 2014 12:52:56 GMTrwbarton<p>
This program prints <tt>("1",2)</tt>, but if you reverse the order of the two instances, it prints <tt>(1,"2")</tt>.
</p>
<pre class="wiki">{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
-- extracted from http://lpaste.net/105656
import Control.Applicative
import Data.Functor.Identity
modify :: ((a -> Identity b) -> s -> Identity t) -> (a -> b) -> (s -> t)
modify l f s = runIdentity (l (Identity . f) s)
class Foo s t a b | a b s -> t where
foo :: Applicative f => (a -> f b) -> s -> f t
instance Foo (x, a) (y, a) x y where
foo f (a,b) = (\fa -> (fa,b)) <$> f a
instance Foo (a, x) (a, y) x y where
foo f (a,b) = (\fb -> (a,fb)) <$> f b
main = print $ modify foo (show :: Int -> String) (1 :: Int, 2 :: Int)
</pre><p>
Note that the two instances involved <tt>Foo (Int, Int) (String, Int) Int String</tt> and <tt>Foo (Int, Int) (Int, String) Int String</tt> are not actually overlapping. But, they have the same <tt>a</tt>, <tt>b</tt>, and <tt>s</tt> fields and it seems that this makes GHC think that either one is equally valid, thanks to the fundep.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9210#changelog
http://ghc.haskell.org/trac/ghc/ticket/9349
http://ghc.haskell.org/trac/ghc/ticket/9349#9349: excessive inlining due to state hackWed, 23 Jul 2014 04:18:58 GMTrwbarton<p>
The program at <a class="ext-link" href="https://gist.github.com/jorendorff/a3005968adc8f054baf7"><span class="icon"></span>https://gist.github.com/jorendorff/a3005968adc8f054baf7</a> runs very slowly when compiled with <tt>-O</tt> or higher. It seems that <tt>arr</tt> and/or <tt>rangeMap</tt> is being inlined into the do block on lines 89-91 and recomputed for each iteration of the loop. The program runs nearly instantly when compiled with <tt>-O0</tt> or with <tt>-O -fno-pre-inlining</tt>. (Of course, this does not mean <tt>-fpre-inlining</tt> is necessary the culprit; it could be enabling some subsequent misoptimization.)
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9349#changelog
http://ghc.haskell.org/trac/ghc/ticket/9430
http://ghc.haskell.org/trac/ghc/ticket/9430#9430: implement more arithmetic operations natively in the LLVM backendSun, 10 Aug 2014 23:08:46 GMTrwbarton<p>
There are a number of arithmetic operations that have native implementations on x86 but use the generic fallback on LLVM. Implementing these with LLVM intrinsics could improve small Integer performance on ARM substantially!
</p>
<pre class="wiki">MO_Add2 @llvm.uadd.with.overflow.*
MO_AddIntC @llvm.sadd.with.overflow.*
MO_SubIntC @llvm.ssub.with.overflow.*
MO_U_Mul2 mul i64/i128?
MO_U_QuotRem2 udiv i64/i128?
</pre>Resultshttp://ghc.haskell.org/trac/ghc/ticket/9430#changelog
http://ghc.haskell.org/trac/ghc/ticket/9431
http://ghc.haskell.org/trac/ghc/ticket/9431#9431: integer-gmp small Integer multiplication does two multiplications on x86Mon, 11 Aug 2014 01:01:45 GMTrwbarton<p>
<tt>timesInteger</tt> begins thusly:
</p>
<pre class="wiki">timesInteger :: Integer -> Integer -> Integer
timesInteger (S# i) (S# j) = if isTrue# (mulIntMayOflo# i j ==# 0#)
then S# (i *# j)
else -- ...
</pre><p>
The x86 backend implements <tt>mulIntMayOflo#</tt> as a (word, word) -> double word multiplication, followed by bit manipulation to test for overflow of the low word. Then, if there was no overflow, on the next line we multiply the operands again.
</p>
<p>
We should be able to do better here. We need a new primop that combines <tt>mulIntMayOflo#</tt> with the actual multiplication result, at least in the non-overflow case (though with some more work we might be able to turn the double word result directly into a large Integer), and then we need to update <tt>timesInteger</tt> to use it.
</p>
<p>
The LLVM backend probably has the same behavior, though it might be smart enough to notice that the multiplication is repeated; I haven't checked its assembly output.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9431#changelog
http://ghc.haskell.org/trac/ghc/ticket/9457
http://ghc.haskell.org/trac/ghc/ticket/9457#9457: hsc2hs breaks with `--cflag=-Werror` in cross-compilation modeTue, 19 Aug 2014 03:54:17 GMTrwbarton<p>
I would like to be able to do
</p>
<pre class="wiki">config_args='--target=i386-unknown-linux --with-gcc=i386-unknown-linux-gcc' ./validate
</pre><p>
to validate a 32-bit GHC on a 64-bit Linux system. (I don't know why I have to specify <tt>--with-gcc</tt> in addition to <tt>--target</tt>; an unrelated mystery.)
</p>
<p>
However <tt>validate</tt> sets <tt>-Werror</tt> and the C code that <tt>hsc2hs</tt> generates in cross-compilation mode is not always warning-free, e.g.,
</p>
<pre class="wiki">Files.hsc: In function ‘_hsc2hs_test’:
Files.hsc:81:14: error: variable ‘test_array’ set but not used [-Werror=unused-but-set-variable]
cc1: all warnings being treated as errors
</pre><p>
so <tt>hsc2hs</tt> draws incorrect conclusions from its tests.
</p>
<p>
Either the <tt>hsc2hs</tt>-generated C code should be made (and kept) warning-free, or perhaps <tt>hsc2hs</tt> should append <tt>-Wwarn</tt> to the options that it passes to the C compiler.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9457#changelog
http://ghc.haskell.org/trac/ghc/ticket/9504
http://ghc.haskell.org/trac/ghc/ticket/9504#9504: LLVM backend TBAA is too aggressiveFri, 22 Aug 2014 19:17:09 GMTrwbarton<p>
At <a class="ext-link" href="https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/Backends/LLVM/Alias#HowtoTrackTBAAinformation"><span class="icon"></span>https://ghc.haskell.org/trac/ghc/wiki/Commentary/Compiler/Backends/LLVM/Alias#HowtoTrackTBAAinformation</a> there is written
</p>
<blockquote class="citation">
<p>
It [a memory load/store] is very rarely of the form:
</p>
<pre class="wiki">x = Sp + 8
I64[x] = ...
</pre><p>
And when it is, 'it is' (unconfirmed) always deriving a "heap" pointer, "stack" pointers are always of the in-line variety.
</p>
</blockquote>
<p>
In fact commit <a class="changeset" href="http://ghc.haskell.org/trac/ghc/changeset/e10589a505b44f4f0394500c6a0d2db5baa7f3f4/ghc" title="Improve LLVM TBAA hierachy (#5567).">e10589a505b44f4f0394500c6a0d2db5baa7f3f4</a> treats any memory access through a Cmm local variable as having the "other" type, which cannot alias any non-"other" address.
</p>
<p>
But it turns out that a Cmm local might be either an offset from Sp (<a class="infoneeded ticket" href="http://ghc.haskell.org/trac/ghc/ticket/9125" title="bug: int-to-float conversion broken on ARM (infoneeded)">#9125</a>, though TBAA doesn't seem to have been the cause of the bad code there) or an offset from a Cmm global variable (<a class="new ticket" href="http://ghc.haskell.org/trac/ghc/ticket/9308" title="bug: nofib fannkuch-redux runs perpetually with -fllvm (new)">#9308</a>). In general, we don't know anything about what it might be so we should conservatively use the "top" "type".
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9504#changelog
http://ghc.haskell.org/trac/ghc/ticket/9611
http://ghc.haskell.org/trac/ghc/ticket/9611#9611: Suggest the cause of "No instance" errors involving multiple versions of a packageFri, 19 Sep 2014 03:47:53 GMTrwbarton<p>
Suppose I have packages A-1.0, A-1.1, and B-1.0 built against A-1.0, and A (both versions) defines a type T which B defines to be an instance of some class C. If I load A-1.1 and B-1.0 into ghci and try to use the C T instance I will get a "No instance for C T" error, because T refers to A-1.1:T and B only defines an instance for A-1.0:T. However, if I don't realize this is what's going on, the error will be quite confusing as B appears to define an instance C T.
</p>
<p>
Or, A could define the class C, rather than the type T, with the same result.
</p>
<p>
This is quite common nowadays because there is a newer version of transformers (0.4.1.0) than the one which ships with GHC (0.3.0.0) and it's easy to end up installing mtl or lens against 0.3.0.0, and then some other package which pulls in 0.4.1.0.
</p>
<p>
It would be nice to give a hint about what is going on, like
</p>
<pre class="wiki">No instance for (MonadIO X) arising from a use of ‘liftIO’
In the expression: ...
...
Note: there is an instance transformers-0.3.0.0:MonadIO X
</pre>Resultshttp://ghc.haskell.org/trac/ghc/ticket/9611#changelog
http://ghc.haskell.org/trac/ghc/ticket/9613
http://ghc.haskell.org/trac/ghc/ticket/9613#9613: when giving an error "No instance for C (a -> b)", suggest that a function may be underappliedFri, 19 Sep 2014 04:05:42 GMTrwbarton<p>
Suggestion of ibotty here: <a class="ext-link" href="http://www.reddit.com/r/haskell/comments/2go92u/beginner_error_messages_in_c_vs_haskell/cklm7jk"><span class="icon"></span>http://www.reddit.com/r/haskell/comments/2go92u/beginner_error_messages_in_c_vs_haskell/cklm7jk</a>
</p>
<pre class="wiki">Prelude> print length
<interactive>:2:1:
No instance for (Show ([a0] -> Int)) arising from a use of ‘print’
but there is an instance for (Show Int);
maybe you omitted an argument to ‘length’ of type [a0]?
In the expression: print length
In an equation for ‘it’: it = print length
</pre><p>
I guess the trickiest part will be figuring out what function is underapplied.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9613#changelog
http://ghc.haskell.org/trac/ghc/ticket/9614
http://ghc.haskell.org/trac/ghc/ticket/9614#9614: ghc --print-(gcc|ld)-linker-flags brokenFri, 19 Sep 2014 05:33:22 GMTrwbarton<pre class="wiki">rwbarton@morphism:~/ghc$ ghc --print-gcc-linker-flags
ghc: panic! (the 'impossible' happened)
(GHC version 7.8.3 for x86_64-unknown-linux):
Setting not found: "Gcc Linker flags"
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
rwbarton@morphism:~/ghc$ ghc --print-ld-linker-flags
ghc: panic! (the 'impossible' happened)
(GHC version 7.8.3 for x86_64-unknown-linux):
Setting not found: "Ld Linker flags"
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
</pre><p>
In <a class="changeset" href="http://ghc.haskell.org/trac/ghc/changeset/2d2650bf65da3aede4e1c1ca4da623092b869dbe/ghc" title="Move linker flags into the settings file; fixes #4862
They were getting ...">2d2650bf65da3aede4e1c1ca4da623092b869dbe</a> and subsequent commits (between 7.6 and 7.8) these settings fields became "C compiler link flags" and "ld flags". (I think, more or less.)
</p>
<p>
The real problem is that Cabal still looks for the settings fields "Gcc Linker flags" and "Ld Linker flags". I guess this should be updated on the Cabal side though. (They are empty on at least Linux x86_64, which I guess is why nobody noticed before.)
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9614#changelog
http://ghc.haskell.org/trac/ghc/ticket/9660
http://ghc.haskell.org/trac/ghc/ticket/9660#9660: unnecessary indirect jump when returning a case scrutineeFri, 03 Oct 2014 03:08:11 GMTrwbarton<p>
I happened to be looking at the Cmm for this code (ghc 7.8.3, -O2)
</p>
<div class="code"><pre><span class="nf">f</span> <span class="ow">::</span> <span class="kt">Int</span> <span class="ow">-></span> <span class="kt">Int</span>
<span class="nf">f</span> x <span class="ow">=</span> <span class="kr">if</span> x <span class="o"><</span> <span class="mi">0</span> <span class="kr">then</span> x <span class="kr">else</span> x<span class="o">+</span><span class="mi">1</span>
</pre></div><p>
and I noticed something a bit funny about it:
</p>
<pre class="wiki"> c12e:
if ((Sp + -8) < SpLim) goto c12z; else goto c12A;
c12z:
R2 = R2;
R1 = Test.f_closure;
call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;
c12A:
I64[Sp - 8] = c12b;
R1 = R2;
Sp = Sp - 8;
if (R1 & 7 != 0) goto c12b; else goto c12c;
c12c:
call (I64[R1])(R1) returns to c12b, args: 8, res: 8, upd: 8;
c12b:
Hp = Hp + 16;
if (Hp > HpLim) goto c12y; else goto c12x;
c12y:
HpAlloc = 16;
R1 = R1;
call stg_gc_unpt_r1(R1) returns to c12b, args: 8, res: 8, upd: 8;
c12x:
_s11Q::I64 = I64[R1 + 7];
if (%MO_S_Lt_W64(_s11Q::I64, 0)) goto c12u; else goto c12v;
c12u:
Hp = Hp - 16;
R1 = R1 & (-8); /* <--- */
Sp = Sp + 8;
call (I64[R1])(R1) args: 8, res: 0, upd: 8; /* <--- */
c12v:
I64[Hp - 8] = GHC.Types.I#_con_info;
I64[Hp] = _s11Q::I64 + 1;
R1 = Hp - 7;
Sp = Sp + 8;
call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
</pre><p>
On the two marked lines, we untag R1 (which is <tt>x</tt>) and enter it. However, we know at this point that <tt>x</tt> is already in WHNF so we could simply return it by replacing the two lines with <tt>call (P64[Sp])(R1)</tt>, if I'm not mistaken. That will save a load and an indirect jump (which we actually know is to <tt>I#_con_info</tt>, which would just retag R1 and return to the address on the stack anyways).
</p>
<p>
I think the same optimization should be available any time we do an algebraic <tt>case</tt> and in a branch simply return the scrutinee.
</p>
<p>
I looked at what it would take to fix this. It looks almost easy: if we add a new <tt>LambdaFormInfo</tt> constructor <tt>LFUnknownCon</tt> meaning that we know the identifier is bound to a saturated application of an unknown constructor, then we could set the <tt>cg_lf</tt> of the case binder variable of an algebraic case statement to <tt>LFUnknownCon</tt>, and return <tt>ReturnIt</tt> for <tt>LFUnknownCon</tt> variables in <tt>getCallMethod</tt>. I think that would do it. Does that sound right? Is there a better way?
</p>
<p>
(In my original example we actually know the constructor has to be <tt>I#</tt>. But if the case was on a type with more than one constructor we wouldn't know statically which one we got, just that it has to be one of them.)
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9660#changelog
http://ghc.haskell.org/trac/ghc/ticket/8303
http://ghc.haskell.org/trac/ghc/ticket/8303#8303: defer StackOverflow exceptions (rather than dropping them) when exceptions are maskedSun, 15 Sep 2013 00:38:12 GMTrwbarton<p>
See <a class="ext-link" href="http://www.reddit.com/r/haskell/comments/1luan1/strange_io_sequence_behaviour/"><span class="icon"></span>http://www.reddit.com/r/haskell/comments/1luan1/strange_io_sequence_behaviour/</a> for a very simple program (<tt>main'</tt>) that accidentally evades the stack size limit, running to completion even though it has allocated hundreds of megabytes of stack chunks, and <a class="ext-link" href="http://www.reddit.com/r/haskell/comments/1luan1/strange_io_sequence_behaviour/cc32ec4"><span class="icon"></span>my comment</a> for an explanation of this behavior.
</p>
<p>
ryani suggested that when a thread exceeds its stack limit but it is currently blocking exceptions, the RTS shouldn't simply drop the <tt>StackOverflow</tt> exception, but rather deliver it when the <tt>mask</tt> operation completes. That sounds sensible to me and it would give a nice guarantee that when any individual <tt>mask</tt> operation uses a small amount of stack, the stack size limit is approximately enforced.
</p>
<p>
(I know that the default stack size limit may go away or essentially go away, but it can still be nice when developing to use a small stack size limit, so that one's system isn't run into the ground by infinite recursion quickly gobbling up tons of memory.)
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/8303#changelog
http://ghc.haskell.org/trac/ghc/ticket/9283
http://ghc.haskell.org/trac/ghc/ticket/9283#9283: bad autoconf variable namesMon, 07 Jul 2014 17:43:47 GMTrwbarton<pre class="wiki">if test "$ac_cv_header_sys_epoll_h" = yes -a "$ac_cv_func_epoll_ctl" = yes; then
AC_DEFINE([HAVE_EPOLL], [1], [Define if you have epoll support.])
fi
if test "$ac_cv_header_sys_event_h" = yes -a "$ac_cv_func_kqueue" = yes; then
AC_DEFINE([HAVE_KQUEUE], [1], [Define if you have kqueue support.])
AC_CHECK_SIZEOF([kev.filter], [], [#include <sys/event.h>
struct kevent kev;])
AC_CHECK_SIZEOF([kev.flags], [], [#include <sys/event.h>
struct kevent kev;])
fi
if test "$ac_cv_header_poll_h" = yes -a "$ac_cv_func_poll" = yes; then
AC_DEFINE([HAVE_POLL], [1], [Define if you have poll support.])
fi
</pre><p>
The <tt>AC_DEFINE</tt> lines for <tt>HAVE_KQUEUE</tt> and <tt>HAVE_POLL</tt> don't do anything, because earlier we have
</p>
<pre class="wiki">AC_CHECK_FUNCS([epoll_ctl eventfd kevent kevent64 kqueue poll])
</pre><p>
and that already defines <tt>HAVE_KQUEUE</tt> (and sets <tt>ac_cv_func_kqueue</tt>) when the <tt>kqueue</tt> function is found.
</p>
<p>
Not entirely sure what the right thing to do is here, do we rely on having a prototype for <tt>kqueue</tt> in <tt>sys/event.h</tt> specifically? Technically that wouldn't be what we check for even if we used a renamed <tt>HAVE_KQUEUE</tt> variable.
</p>
<p>
AFAIK this doesn't cause any real problems except that it really confused me when I tried to simulate not having <tt>poll</tt> by moving <tt>/usr/include/poll.h</tt> away temporarily.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9283#changelog
http://ghc.haskell.org/trac/ghc/ticket/9811
http://ghc.haskell.org/trac/ghc/ticket/9811#9811: constant folding with infinities is wrongTue, 18 Nov 2014 05:48:14 GMTrwbarton<pre class="wiki">main = let big = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
:: Double in
print (big * big - big * big)
</pre><p>
prints NaN when compiled without optimizations but 0.0 when compiled with optimizations.
</p>
<p>
Or, <tt>print (big * big / 2)</tt> prints Infinity when compiled without optimizations but 8.98846567431158e307 when compiled with optimizations (this number is <tt>fromRational (toRational (1/0) / 2)</tt>).
</p>
<p>
The cause is the conversions that go on between Rational and Double in PrelRules (in the functions doubleOp2, mkDoubleVal, convFloating).
</p>
<p>
Ideally, we would have an accurate model of floating-point arithmetic on the target machine, but for now it would be an improvement to just not constant fold when the result is not a finite floating-point number.
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9811#changelog
http://ghc.haskell.org/trac/ghc/ticket/9916
http://ghc.haskell.org/trac/ghc/ticket/9916#9916: ghc -e ":foo bar" exit status is inconsistentMon, 22 Dec 2014 03:35:18 GMTrwbarton<p>
Since <a class="closed ticket" href="http://ghc.haskell.org/trac/ghc/ticket/7962" title="feature request: "ghc -e <invalid expression>" should return non-zero exit status (closed: fixed)">#7962</a> <tt>ghc -e EXPR</tt> exits with status code 1 if <tt>EXPR</tt> fails to compile. While it's undocumented, <tt>ghc -e</tt> does also accept anything that's valid input to GHCi, including GHCi commands like <tt>:t</tt>. In this case, the exit code of <tt>ghc -e</tt> is not always 1 when the command apparently failed. For example, all of:
</p>
<pre class="wiki">ghc -e ':t'
ghc -e ':t +'
ghc -e ':t ='
ghc -e ':t x'
ghc -e ':l nonexistentfile.hs'
</pre><p>
exit with status code 0. But <tt>ghc -e ':l a'</tt> exits with status code 1, because <tt>a</tt> is not a (possible) module name or a source file.
</p>
<p>
(At the code level, <tt>ghc -e ":foo bar"</tt> currently exits with status code 1 when the function for <tt>:foo</tt> raises an exception, and with status code 0 in all other cases.)
</p>
Resultshttp://ghc.haskell.org/trac/ghc/ticket/9916#changelog