Opened 10 years ago

Last modified 5 years ago

#3765 new bug

Rules should "look through" case binders too

Reported by: simonpj Owned by:
Priority: normal Milestone:
Component: Compiler Version: 6.12.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Runtime performance bug Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

Here's a program suggested by Roman

inc :: Int -> Int
{-# INLINE CONLIKE [1] inc #-}
inc n = n+1

dec :: Int -> Int
{-# INLINE [1] dec #-}
dec n = n-1

{-# RULES  "dec/inc" forall n. dec (inc n) = n   #-}

data T = T !Int    -- The bang here prevents the rule firing

foo :: T -> Int
{-# INLINE foo #-}
foo (T n) = dec n + n

bar :: Int -> Int
bar n = foo (T (inc n))

The rule doesn't fire with the bang in the definition of T. If I remove the bang, it fires. It should fire in both cases.

The trouble is that, with the bang, we see something like this (in the output of phase 2 of the simplifier):

Roman.bar =
  \ (n_aat :: GHC.Types.Int) ->
    case Roman.inc n_aat of tpl_X3 { GHC.Types.I# ipv_skx ->
    case Roman.dec tpl_X3 of _ { GHC.Types.I# x_ak2 ->
    GHC.Types.I# (GHC.Prim.+# x_ak2 ipv_skx)
    }

but tpl_X3 is bound to (I# ipv_skx), not to (inc n_aat). Somehow we need both unfoldings for tpl_X3. That seems like a big step, so I'm just capturing the ticket but not actually doing anything about it yet.

Change History (1)

comment:1 Changed 5 years ago by thomie

difficulty: Unknown
Type of failure: None/UnknownRuntime performance bug

Confirmed in HEAD (7.9.20141130).

For reference: the following command shows Rule fired: dec/inc only if the bang is removed.

$ ghc -ddump-rule-firings -fforce-recomp -O T3765.hs

Note: See TracTickets for help on using tickets.