Constant folding for division operations (`quotRem` and `divMod`)
Motivation
I recently noticed that with GHC-9.2 and GHC-9.4 x `quot` 60 `quot` 60
doesn't get constant folded to x `quot` 3600
.
I realised this as I wanted to write a module like the following and expected the function toHours
to be optimised to just a single division, but we get two.
{-# OPTIONS_GHC -O2 -ddump-simpl -ddump-to-file -ddump-stg-final #-}
module Time where
{-# INLINE toHoursMinutesSeconds #-}
toHoursMinutesSeconds :: Int -> (Int, Int, Int)
toHoursMinutesSeconds t = (h, m', s)
where
(h, m') = m `quotRem` 60
(m, s) = toMinutesSeconds t
toMinutesSeconds :: Int -> (Int, Int)
toMinutesSeconds t = t `quotRem` 60
toHours t = h
where
(h, _, _) = toHoursMinutesSeconds t
Proposal
Add constant folding rules for quotRem
and divMod
for repeated division where the remainder is not used, ie, x `quot` y `quot` z = x `quot` (y * z)
and that multiplication is done at compile time.
Edited by Teo Camarasu