[GHC] #15570: Core transformations generate bad indexCharOffAddr# call

GHC ghc-devs at haskell.org
Mon Sep 3 18:27:19 UTC 2018


#15570: Core transformations generate bad indexCharOffAddr# call
-------------------------------------+-------------------------------------
        Reporter:  alpmestan         |                Owner:  alpmestan
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:  8.6.1
       Component:  Compiler          |              Version:  8.5
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by simonpj):

 No I can repro, I can return to the OP.

 I'm deeply puzzled about the case-match on `GHC.Real.even3`.  But leaving
 that aside,
 I'm not so sure that the Core shown in the Description is wrong.  After
 all, suppose
 we made the call
 {{{
 f -9223372036854775808
 }}}
 Then we'd get into the `n<62` branch, so we'd call `chooseChar62` of that
 ridiculous number.

 So semantically, while the code is very strange, it's not actually wrong.

 '''So why do you get a link error'''?  I think that is a bug all by
 itself.
 If I write
 {{{
 x = C# (indexCharOffAddr# "foo"# -9223372036854775808#)
 }}}
 that might seg-fault at runtime, but it should not cause a link error.

 -------------------
 How can stupid code like this arise?  Consider
 {{{
 h :: Int# -> Int#
 h x = let !t = case x of
                  -1000# -> 4#
                  _      -> x
       in
       t +# indexIntOffAddr# "foo"# x)
 }}}
 Notice that `h` unconditionally indexes the string with `x` (just like `f`
 does in the
 Description); presumably the caller is going to guaranteed that `x` is in
 bounds.

 That turns into
 {{{
 h x = case (case x of { -1000 -> 4#; _ -> x }) of
          t -> t +# indexIntOffAddr# "foo"# x
 }}}
 Now case-of-case produces
 {{{
 h x = case x of
          -1000 -> 4# +# indexIntOffAddr# "foo#" x
          _     -> x  +# indexIntOffAddr# "foo#" x
 }}}
 But in the top branch we know that `x` is `-1000`, so we finally get
 {{{
 h x = case x of
          -1000 -> 4# +# indexIntOffAddr# "foo#" -1000
          _     -> x  +# indexIntOffAddr# "foo#" x
 }}}
 This is, in essence, what is happening in the Description.  And it should
 jolly well
 be fine.

 Of course, if the caller never calls the function with `-1000` as the
 argument,
 the top branch will never be executed.
 ------------------
 So my claim so far is: the code is correct; and it's a bug that we get a
 linker error.

 However the code, while correct, is TERRIBLE.  For this function (similar
 to Description, slightly simplified)
 {{{
 go :: Int -> [Char] -> [Char]
 go n cs | n < 62
         = let !c = chooseChar62 n in c : cs
         | otherwise
         = go q cs
         where
           !(q, _) = quotRem n 62
 }}}
 HEAD produces the very civilised result
 {{{
 Bug.$wgo [InlPrag=NOUSERINLINE[2], Occ=LoopBreaker]
   :: Int# -> [Char] -> (# Char, [Char] #)
 [GblId, Arity=2, Caf=NoCafRefs, Str=<S,U><L,U>, Unf=OtherCon []]
 Bug.$wgo
   = \ (ww_s2Ag :: Int#) (w_s2Ad :: [Char]) ->
       case quotRemInt# ww_s2Ag 62# of { (# ipv_a2yf, ipv1_a2yg #) ->
       case <# ww_s2Ag 62# of {
         __DEFAULT -> Bug.$wgo ipv_a2yf w_s2Ad;
         1# ->
           case indexCharOffAddr# lvl_r2Bs ww_s2Ag of wild_X4 { __DEFAULT
 ->
           (# GHC.Types.C# wild_X4, w_s2Ad #)
           }
       }
       }
 }}}
 while the Hadrian build produces the horrible code similar to that above.
 I'll look at that next.

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


More information about the ghc-tickets mailing list