[GHC] #14430: lintUnfolding does not allow unfoldings to jump to enclosing join points

#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points
-------------------------------------+-------------------------------------
Reporter: nomeata | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.3
Keywords: | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
I am not sure why this does not show up in HEAD but it does show up in my
loopification branch. It does look like a bug in GHC to me.
With loopification, I get the following code in the interface of
`Foreign.C.String`:
{{{
d5fd65f7834390bebd0e80edc7b8f627
withCAStringLen1 ::
String
-> (CStringLen -> IO a)
-> State# RealWorld
-> (# State# RealWorld, a #)
{- Arity: 3, HasNoCafRefs,
Strictness: ,
Unfolding: (\ @ a
(str :: String)
(f :: CStringLen -> IO a)
(eta :: State# RealWorld) ->
case lenAcc @ Char str newCAString2 of wild { I# x ->
case newAlignedPinnedByteArray#
@ RealWorld
x
1#
eta of ds2 { (#,#) ipv ipv1 ->
case unsafeFreezeByteArray#
@ RealWorld
ipv1
ipv of ds3 { (#,#) ipv2 ipv3 ->
let {
ptr :: Addr# = byteArrayContents# ipv3
} in
let {
$j :: State# RealWorld -> () -> (# State# RealWorld, a
#)
,
Inline: [~],
Unfolding: InlineRule (3, True, False)
(\ (ds :: [Char])[OneShot]
(n :: Int)[OneShot]
(eta1 :: State#
RealWorld)[OneShot] ->
letrec {
go :: [Char]
-> Int
-> State# RealWorld
-> (# State#
RealWorld, a #)
-}
= \ (w :: State# RealWorld)[OneShot] ->
case (f (Ptr @ CChar ptr, wild)) `cast` (N:IO[0]
<a>_R)
w of ds4 { (#,#) ipv4 ipv5 ->
case touch#
@ 'UnliftedRep
@ ByteArray#
ipv3
ipv4 of s4 { DEFAULT ->
(# s4, ipv5 #) } }
} in
letrec {
$wgo :: [Char]
-> Int# -> State# RealWorld -> (# State#
RealWorld, a #)
, Inline: [0] -}
= \ (w :: [Char]) (ww2 :: Int#) (w1 :: State#
RealWorld) ->
case w of wild1 {
[] -> exit w1
: c cs
-> case c of wild2 { C# c# ->
case writeInt8OffAddr#
@ RealWorld
ptr
ww2
(narrow8Int# (ord# c#))
w1 of s2 { DEFAULT ->
$wgo cs (+# ww2 1#) s2 } } }
} in
$wgo ds ww1 eta1 }
} in
go str newCAString2 ipv2 } } }) -}
}}}
Note how `go` references `j` not only in its RHS, but also in its
unfolding.
When loading this interface, I get this error:
{{{
HC [stage 1] libraries/base/dist-install/build/System/Posix/Internals.o
ghc-stage1: panic! (the 'impossible' happened)
(GHC version 8.3.20171101 for x86_64-unknown-linux):
Iface Lint failure
In interface for Foreign.C.String
Unfolding of go_a6h7
<no location info>: warning:
In the expression: jump $j_a6gX eta2_a6hS ()
Invalid occurrence of a join variable: $j_a6gX
The binder is either not a join point, or not valid here
go_a6h7 = \ (ds_a6hM [OS=OneShot] :: [Char])
(n_a6hN [OS=OneShot] :: Int)
(eta1_a6hO [OS=OneShot] :: State# RealWorld) ->
joinrec {
go_a6hP
:: [Char]
-> Int -> State# RealWorld -> (# State# RealWorld,
a_a6gD #)
[LclId[JoinId(3)], Arity=3]
go_a6hP (ds1_a6hQ :: [Char])
(n1_a6hR :: Int)
(eta2_a6hS :: State# RealWorld)
= case ds1_a6hQ of wild1_a6hT {
[] ->
case n1_a6hR of n2_a6hW { I# ipv4_a6hY ->
jump $j_a6gX eta2_a6hS ()
};
: c_a6i1 cs_a6i2 ->
case n1_a6hR of wild2_a6i4 { I# i_a6i6 ->
case c_a6i1 of wild3_a6i8 { C# c#_a6ia ->
case writeInt8OffAddr#
@ RealWorld ptr_a6gT i_a6i6 (narrow8Int#
(ord# c#_a6ia)) eta2_a6hS
of s2_a6ic
{ __DEFAULT ->
jump go_a6hP cs_a6i2 (I# (+# i_a6i6 1#)) s2_a6ic
}
}
}
}; } in
jump go_a6hP ds_a6hM n_a6hN eta1_a6hO
Iface expr = \ (ds :: [Char])[OneShot]
(n :: Int)[OneShot]
(eta1 :: State# RealWorld)[OneShot] ->
letrec {
go :: [Char]
-> Int -> State# RealWorld -> (# State# RealWorld,
a #)

#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.3 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): The key idea is this: an unfolding is like an extra RHS for the function. So yes, this is a bug. On inspection, it's caused by `lintUnfolding` being called in the wrong place: * We want `lintUnfolding` to be called, once for all, on the unfolding (if any) of each top-level Id; that is, in the `IfaceId` case of `tc_iface_decl`. * But it isn't! Instead `lintUnfolding` is called by `tcPragExpr`, which is called from `tcUnfolding` which is called for each nested unfolding in the interface-file declaration. * This is inefficient, because the top-level call will re-lint the nested unfoldings; and it's wrong for the reason you point out. In the olden days there were no nested unfoldings in interface0-file definitions, which is why this bug got started. Might you fix, Joachim? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14430#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points -------------------------------------+------------------------------------- Reporter: nomeata | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.3 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 nomeata): With these pointers, I can give it a shot. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14430#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points -------------------------------------+------------------------------------- Reporter: nomeata | Owner: nomeata Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.3 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: | -------------------------------------+------------------------------------- Changes (by nomeata): * owner: (none) => nomeata -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14430#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points -------------------------------------+------------------------------------- Reporter: nomeata | Owner: nomeata Type: bug | Status: patch Priority: normal | Milestone: Component: Compiler | Version: 8.3 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D4169 Wiki Page: | -------------------------------------+------------------------------------- Changes (by nomeata): * status: new => patch * differential: => Phab:D4169 Comment: See https://phabricator.haskell.org/D4169 -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14430#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points
-------------------------------------+-------------------------------------
Reporter: nomeata | Owner: nomeata
Type: bug | Status: patch
Priority: normal | Milestone:
Component: Compiler | Version: 8.3
Resolution: | Keywords:
Operating System: Unknown/Multiple | Architecture:
| Unknown/Multiple
Type of failure: None/Unknown | Test Case:
Blocked By: | Blocking:
Related Tickets: | Differential Rev(s): Phab:D4169
Wiki Page: |
-------------------------------------+-------------------------------------
Comment (by Joachim Breitner

#14430: lintUnfolding does not allow unfoldings to jump to enclosing join points -------------------------------------+------------------------------------- Reporter: nomeata | Owner: nomeata Type: bug | Status: closed Priority: normal | Milestone: Component: Compiler | Version: 8.3 Resolution: fixed | Keywords: Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Phab:D4169 Wiki Page: | -------------------------------------+------------------------------------- Changes (by nomeata): * status: patch => closed * resolution: => fixed -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14430#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC