#4308: LLVM compiles Updates.cmm badly
---------------------------------+------------------------------------------
    Reporter:  dterei            |        Owner:  dterei                 
        Type:  bug               |       Status:  new                    
    Priority:  normal            |    Milestone:  7.2.1                  
   Component:  Compiler (LLVM)   |      Version:  6.13                   
    Keywords:                    |     Testcase:                         
   Blockedby:                    |   Difficulty:                         
          Os:  Unknown/Multiple  |     Blocking:                         
Architecture:  x86_64 (amd64)    |      Failure:  Runtime performance bug
---------------------------------+------------------------------------------

Comment(by dterei):

 OK so problem with C call in a branch is due to the LLVM optimiser. In one
 branch the <Rn> stg registers are the <Rn(old)> value while in the branch
 with the C call they're 'undef'. So you would expect there to be a phi
 node like this:

 {{{
 join:
    R3 = phi [lbranch, undef], [rbranch, R3_old]
    ...
 }}}

 However the optimiser doesn't do this as it simplifies phi nodes with
 'undef' values by removing the undef value:

 {{{
 join:
    R3 = R3_old
 }}}

 So this is why we get the bad code. Our undef's are removed by the
 optimiser and so the code generator doesn't know it can let the stg
 registers be trashed.

 When the C call occurs in a non-branch block the 'undef' technique works
 as the llvm optimiser bubbles down the undef value to the tail call, eg:

 {{{
 mid_block:
    store i64 undef R3
    ...
    %0 = call ccc sin()
    ...
    br %final

 final:
    tail call g (Base, Hp, Sp, R1, R2, R3, ...)
 }}}

 Becomes:

 {{{
 mid_block:
    %0 = call ccc sin()
    ...
    br %final

 final:
    tail call g (Base, Hp, Sp, R1, R2, undef, ...)
 }}}


 So how to fix? well could try to change the semantics of 'undef' in LLVM.
 But that seems a risky approach as I don't think the LLVM developers will
 want to do that. Also there is a better way. We change the Cmm
 representation to carry with all calls and jumps the live STG register
 information. Then I don't need to keep passing the stg registers around
 for every call and can free up some registers for intermediate code. Also
 will need to stop the saving and restoring of caller save variables being
 done in Cmm and let LLVM do it instead.

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/4308#comment:6>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to