In the attached code, Foo.foo1 gets compiled (by ghc -O2) into a call to the unspecialized version of Lib.exp5Tail, even though all the related functions are marked INLINE or SPECIALIZE.
The problem seems to be that GHC creates a top-level overloaded function after the specialization pass, so the function never gets specialized.
This might be the same issue as #7785 (closed), but the workaround I posted there does not work here.
Trac metadata
Trac field
Value
Version
7.6.2
Type
Bug
TypeOfFailure
OtherFailure
Priority
normal
Resolution
Unresolved
Component
Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items
0
Show closed items
No child items are currently assigned. Use child items to break down this issue into smaller parts.
Linked items
0
Link issues together to show that they're related or that one is blocking others.
Learn more.
This particular test case needs !ConstraintKinds but I found that the general problem can be reproduced without it. I can try to make a test case that doesn't use !ConstraintKinds if that seems useful.
OK I know what is going on. At the moment we do *no* inlining before specialisation; but in your program you really, really want those INLINE functions to inline before specialisation takes place.
So I made a tiny change to SimplCore:
diff --git a/compiler/simplCore/SimplCore.lhs b/compiler/simplCore/SimplCore.lhsindex 62e167a..86f4f4e 100644--- a/compiler/simplCore/SimplCore.lhs+++ b/compiler/simplCore/SimplCore.lhs@@ -179,7 +179,7 @@ getCoreToDo dflags (base_mode { sm_phase = InitialPhase , sm_names = ["Gentle"] , sm_rules = rules_on -- Note [RULEs enabled in SimplGently]- , sm_inline = False+ , sm_inline = True , sm_case_case = False }) -- Don't do case-of-case transformations. -- This makes full laziness work better
Bingo. We get great code for foo1:
Foo.foo1 = \ (z_ahb :: GHC.Types.Double) (v_ahc :: GHC.Types.Double) -> case v_ahc of _ { GHC.Types.D# x_arD -> case z_ahb of _ { GHC.Types.D# x1_Xsx -> case GHC.Prim.logDouble# x_arD of wild2_ari { __DEFAULT -> case GHC.Prim.logDouble# x1_Xsx of wild3_Xsf { __DEFAULT -> GHC.Types.D# (GHC.Prim.-## (GHC.Prim.*## x_arD (GHC.Prim./## (GHC.Prim.negateDouble# wild2_ari) 120.0)) (GHC.Prim.*## x1_Xsx (GHC.Prim./## (GHC.Prim.negateDouble# wild3_Xsf) 120.0))) } } } }
(Actually to be fair I also eta-expanded foo and bar, but the specialisation takes place nicely either way.)