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 |