Integer inefficiencies
Here is a small program:
module T where
foo :: RealFrac a => a -> a -> Int
{-# INLINE [0] foo #-}
foo x y = truncate $ (y-x)+2
module U where
import T
bar :: Int -> Int
bar x = foo 1 50 + x
GHC 7.2.2 generates this optimal code:
bar = \ (x_abs :: Int) -> case x_abs of _ { I# y_auX -> I# (+# 51 y_auX) }
Whereas the current HEAD generates this:
bar2 :: Integer
bar2 = __integer 2
bar1 :: Int
bar1 =
case doubleFromInteger bar2
of wild_arl { __DEFAULT -> I# (double2Int# (+## 49.0 wild_arl)) }
bar :: Int -> Int
bar = \ (x_a9S :: Int) -> plusInt bar1 x_a9S
If I remove the INLINE pragma from foo, the HEAD generates this:
bar1 :: Int
bar1 =
case doubleFromInteger foo1
of wild_asr { __DEFAULT ->
case GHC.Float.$w$cproperFraction
@ Int GHC.Real.$fIntegralInt (+## 49.0 wild_asr)
of _ { (# ww1_as1, _ #) ->
ww1_as1
}
}
bar :: Int -> Int
bar = \ (x_a9W :: Int) -> plusInt bar1 x_a9W
Interestingly, without the INLINE pragma 7.2.2 doesn't fare much better.
I've also seen this bit in the generated code with the HEAD but not with 7.2.2:
case integerToInt (smallInteger a_s2jL) of wild_a1dA { __DEFAULT -> f wild_a1dA }
I couldn't boil it down to a small test case yet but it leads to a significant performance regression in at least one vector benchmark. I suppose fixing this is only a matter of adding an integerToInt/smallInteger rule.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 7.5 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |