I have a piece of Haskell code that looks like this:
fst . f $ (Z :. i `div` 2)
Z
and :.
are taken from Repa library and are defined like this:
data Z = Z deriving (Show, Read, Eq, Ord)
infixl 3 :.
data tail :. head = !tail :. !head deriving (Show, Read, Eq, Ord)
The expression right of $
defines an array index, while f
is a function that takes that index and returns a pair. This compiles to following Core:
case f_a2pC
(case ># x_s32E 0 of _ {
False ->
case <# x_s32E 0 of _ {
False -> :. Z (I# (quotInt# x_s32E 2));
True -> :. Z (I# (-# (quotInt# (+# x_s32E 1) 2) 1))
};
True ->
case <# x_s32E 0 of _ {
False -> :. Z (I# (quotInt# x_s32E 2));
True -> :. Z (I# (-# (quotInt# (+# x_s32E 1) 2) 1))
}
})
of _ { (x1_a2Cv, _) ->
x1_a2Cv
}
To me it seems obvious (perhaps incorrectly) that the middle case statement (the one with ># x_s32E 0
as scrutinee) is redundant, as both branches are identical. Is there anything I can do to get rid of it? I compile my code using GHC options recommended in Repa documentation: -O2 -Odph -fno-liberate-case -funfolding-use-threshold1000 -funfolding-keeness-factor1000
i
can acutally be legitimately negative, you should usequot
instead ofdiv
. That should fix it. – Picul