Opened 5 years ago

Closed 5 years ago

#7364 closed bug (wontfix)

`foo !f = id . f` becomes non-strict with -O2

Reported by: shachaf Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.6.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Incorrect result at runtime Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

The following program:

foo :: (a -> b) -> a -> b
foo !f = id . f

main :: IO ()
main = print (foo undefined `seq` "ok")

Crashes with Prelude.undefined when compiled without -O2, but prints "ok" with it. As far as I can tell the optimizer shouldn't be allowed to do that.

Change History (6)

comment:1 Changed 5 years ago by ezyang

Looks like a bug in the specializer.

ezyang@javelin:~/Dev/haskell$ ../ghc-build-master/inplace/bin/ghc-stage2 strict.hs -fforce-recomp -O -ddump-spec
[1 of 1] Compiling Main             ( strict.hs, strict.o )

==================== Specialise ====================
Result size of Specialise = {terms: 19, types: 27, coercions: 10}

a_sn2
  :: GHC.Prim.State# GHC.Prim.RealWorld
     -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
[LclId,
 Arity=1,
 Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=1, Value=True,
         ConLike=True, WorkFree=True, Expandable=True,
         Guidance=IF_ARGS [0] 91 60}]
a_sn2 =
  \ (eta_B1 :: GHC.Prim.State# GHC.Prim.RealWorld) ->
    ((System.IO.print
        @ [GHC.Types.Char]
        (GHC.Show.$fShow[] @ GHC.Types.Char GHC.Show.$fShowChar)
        (GHC.Base.build
           @ GHC.Types.Char
           (\ (@ b_amP) -> GHC.CString.unpackFoldrCString# @ b_amP "ok"#)))
     `cast` (GHC.Types.NTCo:IO <()>
             :: GHC.Types.IO ()
                  ~#
                (GHC.Prim.State# GHC.Prim.RealWorld
                 -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #))))
      eta_B1

Main.main :: GHC.Types.IO ()
[LclIdX,
 Arity=1,
 Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
         ConLike=True, WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=True)}]
Main.main =
  a_sn2
  `cast` (Sym (GHC.Types.NTCo:IO <()>)
          :: (GHC.Prim.State# GHC.Prim.RealWorld
              -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #))
               ~#
             GHC.Types.IO ())

a_sn4
  :: GHC.Prim.State# GHC.Prim.RealWorld
     -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
[LclId,
 Arity=1,
 Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=1, Value=True,
         ConLike=True, WorkFree=True, Expandable=True,
         Guidance=IF_ARGS [0] 21 60}]
a_sn4 =
  \ (eta_Xb :: GHC.Prim.State# GHC.Prim.RealWorld) ->
    ((GHC.TopHandler.runMainIO @ () Main.main)
     `cast` (GHC.Types.NTCo:IO <()>
             :: GHC.Types.IO ()
                  ~#
                (GHC.Prim.State# GHC.Prim.RealWorld
                 -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #))))
      eta_Xb

:Main.main :: GHC.Types.IO ()
[LclIdX,
 Arity=1,
 Unf=Unf{Src=<vanilla>, TopLvl=True, Arity=0, Value=True,
         ConLike=True, WorkFree=True, Expandable=True,
         Guidance=ALWAYS_IF(unsat_ok=True,boring_ok=True)}]
:Main.main =
  a_sn4
  `cast` (Sym (GHC.Types.NTCo:IO <()>)
          :: (GHC.Prim.State# GHC.Prim.RealWorld
              -> (# GHC.Prim.State# GHC.Prim.RealWorld, () #))
               ~#
             GHC.Types.IO ())



Linking strict ...

comment:2 Changed 5 years ago by ezyang

Oh, not true, I'm confused about pass ordering; it is a problem with the simplifier, not the specializer.

comment:3 Changed 5 years ago by simonpj

difficulty: Unknown
Milestone: _|_

Indeed. See #5587 and the user manual section. I still don't know how to get good optimisation without accepting this infelicity. Better ideas welcome.

Simon

comment:4 Changed 5 years ago by simonmar

#5587 is marked fixed; maybe we should do the same with this one?

comment:5 Changed 5 years ago by simonpj

Or maybe we should mark both as not-fixed. There is an underlying problem here; it's just that we don't know how to solve it.

comment:6 Changed 5 years ago by simonmar

Resolution: wontfix
Status: newclosed

Yes, good idea - closing as wonfix (the closest we have to "not fixed")

Note: See TracTickets for help on using tickets.