[GHC] #11649: LLVM code generator produces mal-formed LLVM blocks

GHC ghc-devs at haskell.org
Fri Feb 26 11:14:51 UTC 2016


#11649: LLVM code generator produces mal-formed LLVM blocks
-------------------------------------+-------------------------------------
        Reporter:  bgamari           |                Owner:
            Type:  bug               |               Status:  new
        Priority:  highest           |            Milestone:  8.0.1
       Component:  Compiler          |              Version:  8.0.1-rc2
  (CodeGen)                          |
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
 Type of failure:  Compile-time      |  Unknown/Multiple
  crash                              |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

@@ -106,1 +106,1 @@
- Which arose from this Core,
+ Which arose from this Core (from `-ddump-simpl`),

New description:

 It appears that the recent addition
 (673efccb3b348e9daf23d9e65460691bbea8586e) of some instances for types in
 `GHC.Generics` has uncovered a bug in the LLVM code generator (at least on
 ARM). `libraries/base/GHC/Generics.hs` fails to compile with,
 {{{
 Entry block to function must not have predecessors!
 label %cjGw
 /home/ben/ghc/roots/llvm-3.7/bin/opt: libraries/base/GHC/Generics.ll:
 error: input module is broken!
 }}}

 The problematic block in question appears to be,
 {{{
 define internal ghccc void @rhSw_info$def(i32* noalias nocapture
 %Base_Arg, i32* noalias nocapture %Sp_Arg, i32* noal
 ias nocapture %Hp_Arg, i32 %R1_Arg, i32 %R2_Arg, i32 %R3_Arg, i32 %R4_Arg,
 i32 %SpLim_Arg) align 4 nounwind prefix <{
 i32, i32, i32}><{i32 65541, i32 0, i32 15}>
 {
 clpH:
   br label %clpH
 }
 }}}

 Which arose from this Cmm,
 {{{
 ==================== Post control-flow optimisations ====================
 2016-02-26 10:39:28.656744 UTC


 [section ""data" . lvl_rhSw_closure" {
      lvl_rhSw_closure:
          const lvl_rhSw_info;
  },
  lvl_rhSw_entry() //  []
          { info_tbl: [(clpH,
                        label: lvl_rhSw_info
                        rep:HeapRep static { Fun {arity: 1 fun_type:
 ArgSpec 5} })]
            stack_info: arg_space: 0 updfr_space: Nothing
          }
      {offset
        clpH:
            goto clpH;   // CmmBranch
      }
  }]
 }}}

 Which arose from this input Cmm,
 {{{
 ==================== Cmm produced by new codegen ====================
 2016-02-26 10:39:28.611641 UTC

 [section ""data" . lvl_rhSw_closure" {
      lvl_rhSw_closure:
          const lvl_rhSw_info;
  },
  lvl_rhSw_entry() //  [R2]
          { info_tbl: [(clpD,
                        label: lvl_rhSw_info
                        rep:HeapRep static { Fun {arity: 1 fun_type:
 ArgSpec 5} })]
            stack_info: arg_space: 4 updfr_space: Just 4
          }
      {offset
        clpD:
            _shWa::P32 = R2;   // CmmAssign
            goto clpz;   // CmmBranch
        clpz:
            if ((old + 0) - <highSp> < SpLim) goto clpE; else goto clpF;
 // CmmCondBranch
        clpE:
            R2 = _shWa::P32;   // CmmAssign
            R1 = lvl_rhSw_closure;   // CmmAssign
            call (stg_gc_fun)(R2, R1) args: 4, res: 0, upd: 4;   // CmmCall
        clpF:
            goto clpy;   // CmmBranch
        clpy:
            goto shWb;   // CmmBranch
        shWb:
            goto clpH;   // CmmBranch
        clpH:
            goto shWb;   // CmmBranch
      }
  }]
 }}}

 Which arose from this STG,
 {{{#!hs
 lvl_rhSw
   :: forall a_a99i.
      GHC.Generics.U1 a_a99i -> GHC.Generics.U1 [a_a99i]
 [GblId,
  Arity=1,
  Caf=NoCafRefs,
  Str=DmdType <L,U>x,
  Unf=OtherCon []] =
     sat-only \r [eta_shWa]
         let-no-escape {
           some_v_shWb [Occ=LoopBreaker] :: GHC.Generics.U1 [a12_a99i]
           [LclId, Str=DmdType b] =
               NO_CCS[] \u [] some_v_shWb;
         } in  some_v_shWb;
 }}}

 Which arose from this Core (from `-ddump-simpl`),

 {{{#!hs
 lvl_rhSw :: forall a_a99i. U1 a_a99i -> U1 [a_a99i]
 [GblId, Arity=1, Caf=NoCafRefs, Str=DmdType <L,U>x]
 lvl_rhSw =
   \ (@ a12_a99i) _ [Occ=Dead] ->
     letrec {
       some_v_a99l [Occ=LoopBreaker] :: U1 [a12_a99i]
       [LclId, Str=DmdType b]
       some_v_a99l = some_v_a99l; } in
     some_v_a99l
 }}}

 Which is apparently the body of the `some` implementation in the
 `Alternative` instance for `GHC.Generics.U1`.

--

Comment (by bgamari):

 The second-to-last pass output by `verbose-core2core` has this analogue to
 `lvl_rhSw`,
 {{{#!hs
 lvl_sfQZ :: forall a_a99i. U1 a_a99i -> U1 [a_a99i]
 [LclId, Arity=1, Str=DmdType <L,U>x]
 lvl_sfQZ =
   \ (@ a_a99i) (eta_a99j :: U1 a_a99i) ->
     letrec {
       some_v_a99l [Occ=LoopBreaker] :: U1 [a_a99i]
       [LclId, Str=DmdType b]
       some_v_a99l =
         case eta_a99j of wild_XkW [Dmd=<B,U>] { U1 -> some_v_a99l }; } in
     some_v_a99l
 }}}

 It seems that this arose out of,
 {{{#!hs
 $csome_a87d [Occ=LoopBreaker]
   :: forall a_a3vu. U1 a_a3vu -> U1 [a_a3vu]
 [LclId, Arity=1, Str=DmdType]
 $csome_a87d = GHC.Base.$dmsome @ U1 GHC.Generics.$fAlternativeU1
 }}}

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11649#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list